#if defined(TSINGMA_MX) || defined(TSINGMA_GX) || defined(ARCTIC)
#if (FEATURE_MODE == 0)
/**
 @file sys_tmm_dot1ae.c

 @date 2019-1-2

 @version v1.0

 The file contains TMM DOT1AE APIs of sys layer
*/

/***************************************************************
 *
 * Header Files
 *
 ***************************************************************/
#include "sal.h"
#include "ctc_error.h"
#include "ctc_debug.h"
#include "ctc_nexthop.h"
#include "sys_usw_common.h"
#include "sys_tmm_dot1ae.h"
#include "sys_usw_dot1ae.h"
#include "drv_api.h"
#include "sys_usw_scl_api.h"
#include "sys_usw_ftm.h"
#include "sys_usw_port.h"
#include "sys_usw_dma.h"
#include "sys_usw_nexthop_api.h"
#include "sys_usw_interrupt.h"


#define SYS_DOT1AE_SA_NUM  2
#define SYS_TMM_DOT1AE_STATS_NUM 6

extern sys_dot1ae_chan_t *
_sys_usw_dot1ae_chan_lookup(uint8 lchip, uint32 chan_id);


#define __INTERNAL_FUNC__

int32
_sys_tmm_dot1ae_get_bit_set(uint8 bitmap,uint8* bit)
{
    uint8 index = 0;

    if (bitmap == 0)
    {
        return CTC_E_NOT_EXIST;
    }
    for (index = 0; index < 8; index++)
    {
        if (CTC_IS_BIT_SET(bitmap, index))
        {
            *bit = index;
            break;
        }
    }
    return CTC_E_NONE;
}

int32
_sys_tmm_dot1ae_lkup_sec_sa_idx(uint8 lchip,uint8 an,void* p_sec_chan)
{
    int32 idx = 0;
    sys_dot1ae_chan_t* p_sys_sec_chan =NULL;
    p_sys_sec_chan = (sys_dot1ae_chan_t*)p_sec_chan;
    for (idx = 0; idx < 2; idx++)
    {
        if (p_sys_sec_chan->sa_cfg[idx].an == an)
        {
            return idx;
        }
    }
    return CTC_E_NOT_EXIST;
}

int32
_sys_tmm_dot1ae_update_sec_chan_an_en(uint8 lchip,sys_dot1ae_chan_t* p_sys_sec_chan, uint32 an_bitmap,uint8 dp_idx)
{
    uint8 an = 0;
    int32 idx =0;
    uint32 cmd =0;
    uint32 value =0;
    uint32 key_idx=0;
    uint32 encodingSa[4] = {0};

    if (CTC_SLISTCOUNT(p_sys_sec_chan->bind_mem_list))
    {
        for (an = 0; an < MCHIP_CAP(SYS_CAP_DOT1AE_AN_NUM); an++)
        {
            if (CTC_IS_BIT_SET(p_sys_sec_chan->an_valid, an) && (p_sys_sec_chan->dir == CTC_DOT1AE_SC_DIR_RX))
            {
                idx = _sys_tmm_dot1ae_lkup_sec_sa_idx(lchip, an, p_sys_sec_chan);
                if (idx == CTC_E_NOT_EXIST)
                {
                    return idx;
                }
                value = CTC_IS_BIT_SET(an_bitmap, an);
                key_idx = (p_sys_sec_chan->sc_index[dp_idx] << 1) + (idx & 0x1) + (dp_idx? MCHIP_CAP(SYS_CAP_DOT1AE_SEC_CHAN_NUM) : 0);
                cmd = DRV_IOW(DsMacsecReceiveSa_t, DsMacsecReceiveSa_enableReceive_f);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, key_idx, cmd, &value));
            }

            if (!CTC_IS_BIT_SET(an_bitmap, an)
                && (p_sys_sec_chan->dir == CTC_DOT1AE_SC_DIR_TX))
            {
                continue;
            }
            if (CTC_IS_BIT_SET(p_sys_sec_chan->an_valid, an) && (p_sys_sec_chan->dir == CTC_DOT1AE_SC_DIR_TX))
            {
                idx = _sys_tmm_dot1ae_lkup_sec_sa_idx(lchip, an, p_sys_sec_chan);
                if (idx == CTC_E_NOT_EXIST)
                {
                    return idx;
                }

                cmd = DRV_IOR(MacsecTransmitScStatus0_t, MacsecTransmitScStatus0_encodingSa_f);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, dp_idx, cmd, encodingSa));
                if (idx & 0x1)
                {
                    DRV_BIT_SET(encodingSa[p_sys_sec_chan->sc_index[dp_idx] / 32], p_sys_sec_chan->sc_index[dp_idx] % 32);
                }
                else
                {
                    DRV_BIT_UNSET(encodingSa[p_sys_sec_chan->sc_index[dp_idx] / 32], p_sys_sec_chan->sc_index[dp_idx] % 32);
                }
                cmd = DRV_IOW(MacsecTransmitScStatus0_t, MacsecTransmitScStatus0_encodingSa_f);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, dp_idx, cmd, encodingSa));
            }
        }
    }
    return CTC_E_NONE;
}



/*If is_check set, return -1 when port found in bind mem list; if is_check reset, means get gport.*/
 int32
_sys_tmm_dot1ae_sec_chan_lkup_port(uint8 lchip, uint8 is_check, uint32* p_port, sys_dot1ae_chan_t* p_sys_sec_chan)
{
    ctc_slistnode_t* node = NULL;
    sys_dot1ae_chan_bind_node_t* p_sec_chan_bind_node = NULL;
    if (CTC_SLISTCOUNT(p_sys_sec_chan->bind_mem_list))
    {
        if ((0 == p_sys_sec_chan->binding_type) && !is_check)
        {
            node = p_sys_sec_chan->bind_mem_list->head;
            p_sec_chan_bind_node = _ctc_container_of(node, sys_dot1ae_chan_bind_node_t, head);
            *p_port = p_sec_chan_bind_node->value;
        }
        else
        {
            CTC_SLIST_LOOP(p_sys_sec_chan->bind_mem_list, node)
            {
                p_sec_chan_bind_node = _ctc_container_of(node, sys_dot1ae_chan_bind_node_t, head);
                if (p_sec_chan_bind_node->value == *p_port)
                {
                    return - 1;
                }
            }
        }
    }
    return CTC_E_NONE;
}

STATIC int32
_sys_tmm_dot1ae_reset_sec_chan_cfg(uint8 lchip,     sys_dot1ae_chan_t* p_sc_info,uint8 dp_id)
{
    uint32 cmd = 0;
    uint32 value[2] = {0};
    uint16  key_index   = 0;
    uint32 sc_index =0;
    uint8 loop = 0;
    uint32 sci_hw[2] =   {0};
    uint32 nextAnReady[4] = {0};
    uint32 tmp=0;
    ds_t ds;
    sal_memset(&ds, 0, sizeof(ds));
    for (loop = 0; loop < MCHIP_CAP(SYS_CAP_DOT1AE_AN_NUM); loop++)
    {
        key_index = (p_sc_info->sc_index[dp_id] << 1) + (loop & 0x1) +( dp_id ?MCHIP_CAP(SYS_CAP_DOT1AE_SEC_CHAN_NUM):0);

        /*next pn/windown size*/
        if (p_sc_info->dir == CTC_DOT1AE_SC_DIR_TX)
        {
            value[0] = 1;
            cmd = DRV_IOW(DsMacsecTransmitSaPn_t, DsMacsecTransmitSaPn_macsecPn_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, key_index, cmd, value));

            /*an */
            cmd = DRV_IOW(DsMacsecTransmitSa_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, key_index, cmd, &ds));
        }
        else
        {
            value[0] = 1;
            cmd = DRV_IOW(DsMacsecReceiveSaStatus_t, DsMacsecReceiveSaStatus_nextPn_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, key_index, cmd, value));

            cmd = DRV_IOW(DsMacsecReceiveSa_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, key_index, cmd, &ds));
        }

    }

    sc_index = p_sc_info->sc_index[dp_id] + (dp_id? MCHIP_CAP(SYS_CAP_DOT1AE_TX_CHAN_NUM) : 0);
    if (p_sc_info->dir == CTC_DOT1AE_SC_DIR_RX)
    {

        /*DsMacsecReceiveSc*/
        tmp = 0;
        cmd = DRV_IOW(DsMacsecReceiveSc_t, DsMacsecReceiveSc_macsecPnExhaustInterruptEn_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, sc_index, cmd, &tmp));
        tmp = 0;
        cmd = DRV_IOW(DsMacsecReceiveSc_t, DsMacsecReceiveSc_macsecPnReachMaxInterruptEn_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, sc_index, cmd, &tmp));

        cmd = DRV_IOW(DsMacsecReceiveSc_t, DsMacsecReceiveSc_sci_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip,  sc_index , cmd, sci_hw));
    }
    else
    {
        /*DsMacsecTransmitSc*/
        cmd = DRV_IOR(DsMacsecTransmitSc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_index, cmd, &ds));
        SetDsMacsecTransmitSc(V, macsecPnInterruptEn_f, &ds, 0);
        SetDsMacsecTransmitSc(V, macsecPnReachMaxInterruptEn_f, &ds, 0);
        SetDsMacsecTransmitSc(V, discardUninUseSaPkt_f, &ds, 1);
        cmd = DRV_IOW(DsMacsecTransmitSc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_index, cmd, &ds));

        cmd = DRV_IOW(DsMacsecTransmitSc_t, DsMacsecTransmitSc_sci_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip,  sc_index , cmd, sci_hw));

        /*nextAnReady*/
        cmd = DRV_IOR(MacsecTransmitScStatus1_t, MacsecTransmitScStatus1_nextAnReady_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, dp_id, cmd, nextAnReady));
        DRV_BIT_SET(nextAnReady[p_sc_info->sc_index[dp_id] / 32], p_sc_info->sc_index[dp_id] % 32);
        cmd = DRV_IOW(MacsecTransmitScStatus1_t, MacsecTransmitScStatus1_nextAnReady_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, dp_id, cmd, nextAnReady));
    }
    return CTC_E_NONE;
}

int32
sys_tmm_dot1ae_reset_sec_chan_cfg(uint8 lchip,     void* sys_chan)
{
    sys_dot1ae_chan_t* p_sys_chan = (sys_dot1ae_chan_t*)sys_chan;

    SYS_DOT1AE_FOREACH_DP_BEGIN(p_sys_chan->dp_bmp)
    CTC_ERROR_RETURN(_sys_tmm_dot1ae_reset_sec_chan_cfg(lchip, p_sys_chan,dp_idx));
    SYS_DOT1AE_FOREACH_DP_END
   
    return CTC_E_NONE;

}

 int32 _sys_tmm_dot1ae_sync_dma_traverse(sys_dot1ae_chan_t* p_sys_chan,void* user_data)
 {
     uint8 lchip = 0;
     uint32 secYId = 0;
     uint8 type = 0;
     uint32 i = 0;
     uint32 sc_index =0;
     uint32* p_addr =NULL;
     sys_traverse_t* traversal_data = (sys_traverse_t *)user_data;
     uint32 dword = 0;
     DsMacsecByteStats_s* p_Macsec_ByteStats = NULL;
     uint64 tmp = 0;
     uint8 tmp_dir=0;
     sys_tmm_dot1ae_an_stats_t* p_sys_stats = (sys_tmm_dot1ae_an_stats_t*)(p_sys_chan->an_stats);
     
     lchip = traversal_data->value1;
     type = traversal_data->value2;

     tmp_dir = (type%SYS_TMM_DOT1AE_STATS_NUM < SYS_TMM_DOT1AE_STATS_NUM / 2)? CTC_DOT1AE_SC_DIR_RX : CTC_DOT1AE_SC_DIR_TX;

     if (tmp_dir != p_sys_chan->dir)
     {
        return CTC_E_NONE;
     }

     p_addr = (uint32*)traversal_data->data;
     if (CTC_SLISTCOUNT(p_sys_chan->bind_mem_list))
     {
         SYS_DOT1AE_FOREACH_DP_BEGIN(p_sys_chan->dp_bmp)
         switch (type%SYS_TMM_DOT1AE_STATS_NUM)
         {
             case 0 :      /*DsMacsecSecYStats*/
                 dword = TABLE_ENTRY_OFFSET(lchip, DsMacsecSecYStats_t)>>2;
                 for (i = 0; i < MCHIP_CAP(SYS_CAP_DOT1AE_SEC_CHAN_NUM); i++)
                 {
                     secYId  = sys_tmm_dot1ae_get_secyid(lchip, p_sys_chan->chan_id,dp_idx);
                     if ((secYId == i) && (type / SYS_TMM_DOT1AE_STATS_NUM == dp_idx))
                     {
                         p_sys_stats[0].in_pkts_badtag += *(p_addr + (secYId - (dp_idx? MCHIP_CAP(SYS_CAP_DOT1AE_TX_CHAN_NUM) : 0))*dword);
                         p_sys_stats[0].in_pkts_not_using_sa += *(p_addr + (secYId - (dp_idx? MCHIP_CAP(SYS_CAP_DOT1AE_TX_CHAN_NUM) : 0))*dword + 1);
                         p_sys_stats[0].in_pkts_unused_sa += *(p_addr + (secYId - (dp_idx? MCHIP_CAP(SYS_CAP_DOT1AE_TX_CHAN_NUM) : 0))*dword + 2);
                     }
                 }
                 break;
             case 1 :      /*DsMacsecScStats*/
                 dword = TABLE_ENTRY_OFFSET(lchip, DsMacsecScStats_t)>>2;
                 for (i = 0; i < MCHIP_CAP(SYS_CAP_DOT1AE_SEC_CHAN_NUM); i++)
                 {
                         sc_index = (p_sys_chan->sc_index[dp_idx]) + (dp_idx? MCHIP_CAP(SYS_CAP_DOT1AE_TX_CHAN_NUM) : 0);
                         if ((sc_index == i)&& (type/SYS_TMM_DOT1AE_STATS_NUM == dp_idx))
                         {
                             p_sys_stats[0].in_pkts_ok += *(p_addr + (sc_index-(dp_idx?MCHIP_CAP(SYS_CAP_DOT1AE_TX_CHAN_NUM):0))*dword);
                             p_sys_stats[0].in_pkts_unchecked += *(p_addr + (sc_index-(dp_idx?MCHIP_CAP(SYS_CAP_DOT1AE_TX_CHAN_NUM):0))*dword + 1);
                             p_sys_stats[0].in_pkts_delayed += *(p_addr + (sc_index-(dp_idx?MCHIP_CAP(SYS_CAP_DOT1AE_TX_CHAN_NUM):0))*dword + 2);
                             p_sys_stats[0].in_pkts_late += *(p_addr + (sc_index-(dp_idx?MCHIP_CAP(SYS_CAP_DOT1AE_TX_CHAN_NUM):0))*dword + 3);
                             p_sys_stats[0].in_pkts_invalid += *(p_addr + (sc_index-(dp_idx?MCHIP_CAP(SYS_CAP_DOT1AE_TX_CHAN_NUM):0))*dword + 4);
                             p_sys_stats[0].in_pkts_not_valid += *(p_addr + (sc_index-(dp_idx?MCHIP_CAP(SYS_CAP_DOT1AE_TX_CHAN_NUM):0))*dword + 5);
                         }
                 }
                 break;
             case 2 :     /*DsMacsecSecYByteStats*/
                 dword = TABLE_ENTRY_OFFSET(lchip, DsMacsecSecYByteStats_t)>>2;
                 for (i = 0; i < MCHIP_CAP(SYS_CAP_DOT1AE_SEC_CHAN_NUM); i++)
                 {
                     secYId  = sys_tmm_dot1ae_get_secyid(lchip, p_sys_chan->chan_id,dp_idx);
                     if ((secYId == i) && (type / SYS_TMM_DOT1AE_STATS_NUM == dp_idx))
                     {
                         p_Macsec_ByteStats = (DsMacsecByteStats_s*)(p_addr + (secYId - (dp_idx? MCHIP_CAP(SYS_CAP_DOT1AE_TX_CHAN_NUM) : 0))*dword);
                         tmp = p_Macsec_ByteStats->array_0_byteCount_5_0;
                         tmp <<= 32;
                         tmp |= p_Macsec_ByteStats->array_0_byteCount_31_0;
                         p_sys_stats[0].in_octets_decrypted += tmp;
                         tmp = p_Macsec_ByteStats->array_1_byteCount_5_0;
                         tmp <<= 32;
                         tmp |= p_Macsec_ByteStats->array_1_byteCount_31_0;
                         p_sys_stats[0].in_octets_validated += tmp;
                     }
                     
                 }
                 break;
             case 3 :     /*DsMacsecDestSecYStats*/
                 dword = TABLE_ENTRY_OFFSET(lchip, DsMacsecDestSecYStats_t)>>2;
                 for (i = 0; i < MCHIP_CAP(SYS_CAP_DOT1AE_SEC_CHAN_NUM); i++)
                 {
                     secYId  = sys_tmm_dot1ae_get_secyid(lchip, p_sys_chan->chan_id, dp_idx);
                     if ((secYId == i) && (type / SYS_TMM_DOT1AE_STATS_NUM == dp_idx))
                     {
                         p_sys_stats[0].out_pkts_untagged += *(p_addr + (secYId - (dp_idx? MCHIP_CAP(SYS_CAP_DOT1AE_TX_CHAN_NUM) : 0))*dword);
                         p_sys_stats[0].out_pkts_toolong += *(p_addr + (secYId - (dp_idx? MCHIP_CAP(SYS_CAP_DOT1AE_TX_CHAN_NUM) : 0))*dword + 1);
                     }
                     
                 }
                 break;
             case 4 :     /*DsMacsecTransmitScStats*/
                 dword = TABLE_ENTRY_OFFSET(lchip, DsMacsecTransmitScStats_t)>>2;
                 for (i = 0; i < MCHIP_CAP(SYS_CAP_DOT1AE_SEC_CHAN_NUM); i++)
                 {

                     sc_index = (p_sys_chan->sc_index[dp_idx]) + (dp_idx? MCHIP_CAP(SYS_CAP_DOT1AE_TX_CHAN_NUM) : 0);
                     if ((sc_index == i) && (type / SYS_TMM_DOT1AE_STATS_NUM == dp_idx))
                     {
                         p_sys_stats[0].out_pkts_encrypted += *(p_addr + (sc_index - (dp_idx? MCHIP_CAP(SYS_CAP_DOT1AE_TX_CHAN_NUM) : 0))*dword);
                         p_sys_stats[0].out_pkts_protected += *(p_addr + (sc_index - (dp_idx? MCHIP_CAP(SYS_CAP_DOT1AE_TX_CHAN_NUM) : 0))*dword + 1);
                         p_sys_stats[0].out_pkts_sa_not_inuse += *(p_addr + (sc_index - (dp_idx? MCHIP_CAP(SYS_CAP_DOT1AE_TX_CHAN_NUM) : 0))*dword + 2);
                     }
                     
                 }
                 break;
             case 5 :     /*DsMacsecDestSecYByteStats*/
                 dword = TABLE_ENTRY_OFFSET(lchip, DsMacsecDestSecYByteStats_t)>>2;
                 for (i = 0; i < MCHIP_CAP(SYS_CAP_DOT1AE_SEC_CHAN_NUM); i++)
                 {
                     secYId  = sys_tmm_dot1ae_get_secyid(lchip, p_sys_chan->chan_id,dp_idx);
                     if ((secYId == i) && (type / SYS_TMM_DOT1AE_STATS_NUM == dp_idx))
                     {
                         p_Macsec_ByteStats = (DsMacsecByteStats_s*)(p_addr + (secYId - (dp_idx? MCHIP_CAP(SYS_CAP_DOT1AE_TX_CHAN_NUM) : 0))*dword);
                         tmp = p_Macsec_ByteStats->array_0_byteCount_5_0;
                         tmp <<= 32;
                         tmp |= p_Macsec_ByteStats->array_0_byteCount_31_0;
                         p_sys_stats[0].out_octets_encrypted += tmp;
                         tmp = p_Macsec_ByteStats->array_1_byteCount_5_0;
                         tmp <<= 32;
                         tmp |= p_Macsec_ByteStats->array_1_byteCount_31_0;
                         p_sys_stats[0].out_octets_protected += tmp;
                     }
                     
                 }
                 break;
             default:
                 break;
         }
     SYS_DOT1AE_FOREACH_DP_END
     }
     return CTC_E_NONE;
 }

int32
sys_tmm_dot1ae_build_sc_index(uint8 lchip, void* sys_chan)
{
    uint32  offset = 0;
    sys_dot1ae_chan_t* p_sys_chan = (sys_dot1ae_chan_t*)sys_chan;
    uint32 dp_id = 0;
    uint32 chan_id =0;
    uint8 index = 0;
    uint32 index2 = 0;
    sys_usw_opf_t opf;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    opf.pool_type = usw_dot1ae_master[lchip]->dot1ae_opf_type;

    /* 1. Get sub chan id using gport */
    dmps_port_info.gport = p_sys_chan->gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &chan_id));

    /* 2. Build sc index per dp */
    if (p_sys_chan->binding_type)
    {
        uint8 found = 0;
        p_sys_chan->macsecType = 1;
        for (index2 = 0; index2 < MCHIP_CAP(SYS_CAP_DOT1AE_TX_CHAN_NUM); index2++)
        {
            if (p_sys_chan->dir == CTC_DOT1AE_SC_DIR_TX)
            {
                if ((!CTC_BMP_ISSET(usw_dot1ae_master[lchip]->dp0_tx_bmp, index2)) && (!CTC_BMP_ISSET(usw_dot1ae_master[lchip]->dp1_tx_bmp, index2)))
                {
                    found = 1;
                    CTC_BMP_SET(usw_dot1ae_master[lchip]->dp0_tx_bmp, index2);
                    CTC_BMP_SET(usw_dot1ae_master[lchip]->dp1_tx_bmp, index2);
                    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_DOT1AE, SYS_WB_APPID_DOT1AE_SUBID_MASTER, 1);
                    break;
                }
            }
            else
            {
                if ((!CTC_BMP_ISSET(usw_dot1ae_master[lchip]->dp0_rx_bmp, index2)) && (!CTC_BMP_ISSET(usw_dot1ae_master[lchip]->dp1_rx_bmp, index2)))
                {
                    found = 1;
                    CTC_BMP_SET(usw_dot1ae_master[lchip]->dp0_rx_bmp, index2);
                    CTC_BMP_SET(usw_dot1ae_master[lchip]->dp1_rx_bmp, index2);
                    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_DOT1AE, SYS_WB_APPID_DOT1AE_SUBID_MASTER, 1);
                    break;
                }
            }
        }
        if (found == 0)
        {
            return CTC_E_NO_RESOURCE;
        }
        for (index = 0; index < 2; index++)
        {
            opf.pool_index = ((p_sys_chan->dir == CTC_DOT1AE_SC_DIR_TX) ? 0 : 1) + 2*index;
            CTC_ERROR_RETURN(sys_usw_opf_alloc_offset_from_position(lchip, &opf, 1, index2));
        }
        p_sys_chan->sc_index[0] = index2;
        p_sys_chan->sc_index[1] = index2;
        p_sys_chan->dp_bmp = 0x3;
        p_sys_chan->alloced_source = 1;
    }
    else
    {
        dp_id = chan_id >= MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM);
        opf.pool_index = ((p_sys_chan->dir == CTC_DOT1AE_SC_DIR_TX) ? 0 : 1) + (dp_id? 2 : 0);
        CTC_ERROR_RETURN(sys_usw_opf_alloc_offset(lchip, &opf, 1, &offset));
        p_sys_chan->sc_index[dp_id] = offset&0x7F;
        CTC_BIT_SET(p_sys_chan->dp_bmp, dp_id);
        p_sys_chan->dp_id = dp_id;
        CTC_BMP_SET((p_sys_chan->dir == CTC_DOT1AE_SC_DIR_TX)? (dp_id? usw_dot1ae_master[lchip]->dp1_tx_bmp : usw_dot1ae_master[lchip]->dp0_tx_bmp)
        : (dp_id? usw_dot1ae_master[lchip]->dp1_rx_bmp : usw_dot1ae_master[lchip]->dp0_rx_bmp), offset);
    }
    return CTC_E_NONE;
}


int32
sys_tmm_dot1ae_free_sc_index(uint8 lchip, void* sys_chan)
{
    sys_dot1ae_chan_t* p_sys_chan = (sys_dot1ae_chan_t*)sys_chan;
    sys_usw_opf_t opf;

    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    opf.pool_type = usw_dot1ae_master[lchip]->dot1ae_opf_type;
    SYS_DOT1AE_FOREACH_DP_BEGIN(p_sys_chan->dp_bmp)
    opf.pool_index = ((p_sys_chan->dir == CTC_DOT1AE_SC_DIR_TX) ? 0 : 1) + (dp_idx? 2 : 0);
    sys_usw_opf_free_offset(lchip, &opf, 1, p_sys_chan->sc_index[dp_idx]);
    SYS_DOT1AE_FOREACH_DP_END

    return CTC_E_NONE;
}


int32
_sys_tmm_dot1ae_get_chan_traverse(sys_dot1ae_chan_t* p_sys_chan,void* user_data)
{
    uint32 gport = 0;
    sys_dot1ae_chan_bind_node_t* p_sec_chan_bind_node = NULL;
    ctc_slistnode_t        *node = NULL;
    sys_com_dot1ae_bind_sc_t* p_bind_sc = NULL;
    sys_traverse_t* traversal_data = (sys_traverse_t *)user_data;
    p_bind_sc = (sys_com_dot1ae_bind_sc_t*)traversal_data->data;
    gport = p_bind_sc->gport;

    if (CTC_SLISTCOUNT(p_sys_chan->bind_mem_list)
        &&(p_sys_chan->dir == p_bind_sc->dir))
    {
        node = p_sys_chan->bind_mem_list->head;
        p_sec_chan_bind_node = _ctc_container_of(node, sys_dot1ae_chan_bind_node_t, head);
        if (gport == p_sec_chan_bind_node->value)
        {
            traversal_data->value2 = p_sys_chan->chan_id;
            return - 2;
        }
    }
    return CTC_E_NONE;
}
#if 0
STATIC int32
_sys_tmm_dot1ae_get_chan_by_idx_traverse(sys_dot1ae_chan_t* p_sys_chan,void* user_data)
{
    sys_dot1ae_chan_t* p_tmp_sys_chan = NULL;
    sys_traverse_t* traversal_data = (sys_traverse_t *)user_data;
    p_tmp_sys_chan = (sys_dot1ae_chan_t*)traversal_data->data;

    if ((CTC_SLISTCOUNT(p_sys_chan->bind_mem_list)
        ||(p_sys_chan->binded &&(DRV_FROM_AT(traversal_data->value1))))
        && (p_sys_chan->dir == p_tmp_sys_chan->dir)
    && (p_sys_chan->dp_id == p_tmp_sys_chan->dp_id)
    && (p_sys_chan->sc_index == p_tmp_sys_chan->sc_index))
    {
        sal_memcpy(p_tmp_sys_chan,p_sys_chan,sizeof(sys_dot1ae_chan_t));
    }

    return CTC_E_NONE;
}
#endif

int32
_sys_tmm_dot1ae_unbind_traverse(sys_dot1ae_chan_t* p_sys_chan,void* user_data)
{
    uint32 gport = 0;
    uint8 lchip=0;
    uint32 value =0;
    sys_usw_opf_t opf;
    ctc_slistnode_t        *node = NULL;
    uint32 cmd=0;
    uint32 secYId =0;
    uint8 found = 0;
    uint32 enableTransmit[8] ={0};
    uint8 idx=0;
    uint32 dot1ae_en[4] = {0};

    sys_dot1ae_chan_bind_node_t* p_sec_chan_bind_node = NULL;
    sys_com_dot1ae_bind_sc_t* p_bind_sc = NULL;
    sys_traverse_t* traversal_data = (sys_traverse_t *)user_data;
    p_bind_sc = (sys_com_dot1ae_bind_sc_t*)traversal_data->data;
    gport = p_bind_sc->gport;
    lchip = traversal_data->value1;
    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    if (p_sys_chan->valid&& CTC_SLISTCOUNT(p_sys_chan->bind_mem_list)
        &&(p_sys_chan->binding_type == p_bind_sc->type)&&
        (p_sys_chan->dir == p_bind_sc->dir))
        {
            CTC_SLIST_LOOP(p_sys_chan->bind_mem_list, node)
            {
                p_sec_chan_bind_node = _ctc_container_of(node, sys_dot1ae_chan_bind_node_t, head);
                if ((p_sys_chan->chan_id == p_bind_sc->chan_id) || (gport == p_sec_chan_bind_node->value))
                {
                    found = 1;
                    break;
                }
            }
            if (1 == found)
            {
                if (CTC_SLISTCOUNT(p_sys_chan->bind_mem_list)==1)
                {
                    opf.pool_type = usw_dot1ae_master[lchip]->dot1ae_opf_type;
                    SYS_DOT1AE_FOREACH_DP_BEGIN(p_sys_chan->dp_bmp)
                    opf.pool_index = ((p_sys_chan->dir == CTC_DOT1AE_SC_DIR_TX) ? 0 : 1) + (dp_idx? 2 : 0);
                    sys_usw_opf_free_offset(lchip, &opf, 1, p_sys_chan->sc_index[dp_idx]);
                    CTC_BMP_UNSET((p_sys_chan->dir == CTC_DOT1AE_SC_DIR_TX)? (dp_idx? usw_dot1ae_master[lchip]->dp1_tx_bmp : usw_dot1ae_master[lchip]->dp0_tx_bmp)
                    : (dp_idx? usw_dot1ae_master[lchip]->dp1_rx_bmp : usw_dot1ae_master[lchip]->dp0_rx_bmp), p_sys_chan->sc_index[dp_idx]);
                    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_DOT1AE, SYS_WB_APPID_DOT1AE_SUBID_MASTER, 1);

                    /* Disable macsec on channel */
                    secYId = sys_tmm_dot1ae_get_secyid(lchip, p_sys_chan->chan_id,dp_idx);
                    if (p_sys_chan->dir == CTC_DOT1AE_SC_DIR_TX)
                    {
                        cmd = DRV_IOR(MacsecTransmitSaStatus_t, MacsecTransmitSaStatus_enableTransmit_f);
                        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, dp_idx, cmd, enableTransmit));
                        for (idx = 0; idx < 2; idx++)
                        {
                            uint32 sa_idx = (p_sys_chan->sc_index[dp_idx] << 1) + idx;
                            CTC_BIT_UNSET(enableTransmit[sa_idx / 32], sa_idx % 32);
                            cmd = DRV_IOW(MacsecTransmitSaStatus_t, MacsecTransmitSaStatus_enableTransmit_f);
                            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, dp_idx, cmd, enableTransmit));
                        }

                        value = 0;
                        cmd = DRV_IOW(DsMacsecDestSecY_t, DsMacsecDestSecY_macsecEnable_f);
                        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, secYId, cmd, &value));

                        if (SYS_DOT1AE_BIND_TYPE_NEXTHOP == p_sys_chan->binding_type)
                        {
                            cmd = DRV_IOW(DsMacsecDestSecYPre_t, DsMacsecDestSecYPre_isAdvSecY_f);
                            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, secYId, cmd, &value));
                        }
                    }
                    else
                    {
                        secYId = dp_idx? (secYId - MCHIP_CAP(SYS_CAP_DOT1AE_TX_CHAN_NUM)) : secYId;
                        cmd = DRV_IOR(DsMacsecSrcChannel_t, DsMacsecSrcChannel_p2pMacsecEnable_f);
                        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, dp_idx, cmd, dot1ae_en));
                        CTC_BIT_UNSET(dot1ae_en[secYId / 32], secYId % 32);
                        cmd = DRV_IOW(DsMacsecSrcChannel_t, DsMacsecSrcChannel_p2pMacsecEnable_f);
                        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, dp_idx, cmd, dot1ae_en));
                        for (idx = 0; idx < 2; idx++)
                        {
                            uint32 sa_idx = (p_sys_chan->sc_index[dp_idx] << 1) + idx;
                            value = 0;
                            cmd = DRV_IOW(DsMacsecReceiveSa_t, DsMacsecReceiveSa_enableReceive_f);
                            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, sa_idx, cmd, &value));
                        }
                    }
                    p_sys_chan->enable = 0;
                    p_sys_chan->sc_index[0] = 0;
                    p_sys_chan->sc_index[1] = 0;
                    p_sys_chan->binded = 0;
                    SYS_DOT1AE_FOREACH_DP_END
                }
                ctc_slist_delete_node(p_sys_chan->bind_mem_list, &(p_sec_chan_bind_node->head));
                mem_free(p_sec_chan_bind_node);
            }
        }
    return CTC_E_NONE;
}

int32
_sys_tmm_dot1ae_p2mp_en_sec_chan(sys_dot1ae_chan_t* p_sys_chan,void* user_data)
{
    uint32 gport = 0;
    ctc_slistnode_t        *node = NULL;
    sys_dot1ae_chan_bind_node_t* p_sec_chan_bind_node = NULL;
    sys_com_dot1ae_bind_sc_t* p_bind_sc = NULL;
    sys_traverse_t* traversal_data = (sys_traverse_t *)user_data;
    p_bind_sc = (sys_com_dot1ae_bind_sc_t*)traversal_data->data;
    gport = p_bind_sc->gport;

    if (CTC_SLISTCOUNT(p_sys_chan->bind_mem_list) &&(p_sys_chan->p2mp||p_sys_chan->clear_tag_en))
    {
        node = p_sys_chan->bind_mem_list->head;
        p_sec_chan_bind_node = _ctc_container_of(node, sys_dot1ae_chan_bind_node_t, head);
        if (gport == p_sec_chan_bind_node->value)
        {
            p_sys_chan->enable = p_bind_sc->dot1AE_RX_En || p_bind_sc->dot1AE_TX_En;
        }
    }
    return CTC_E_NONE;
}
#if 0
STATIC int32
_sys_tmm_dot1ae_isr_get_defect_name(uint8 lchip, ctc_dot1ae_event_entry_t* intrp_info)
{
    uint8 index = 0;

    for (index = 0; index < 3; index++)
    {
        if (CTC_IS_BIT_SET(intrp_info->event_bmp, index))
        {
            switch (1<<index)
            {
                case CTC_DOT1AE_EVENT_PN_OVER_FLOW:
                    SYS_DOT1AE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "  Event name: %s\r\n", " PN exhaust.");
                    break;
                default:
                    break;
            }
        }
    }
    return CTC_E_NONE;
}
#endif
STATIC int32
_sys_tmm_dot1ae_add_sc_to_asic(uint8 lchip, sys_dot1ae_chan_t* p_sys_chan,uint8 dp_id)
{
    uint8 secYId = 0;
    uint32 cmd = 0;
    uint32 value = 0;
    uint32 sci_hw[2] ={0};
    uint32 sc_idx = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};
    sc_idx = (p_sys_chan->sc_index[dp_id]) + (dp_id? MCHIP_CAP(SYS_CAP_DOT1AE_TX_CHAN_NUM) : 0);

    if (p_sys_chan->p2mp || p_sys_chan->clear_tag_en)
    {
        dmps_port_info.gport = p_sys_chan->gport;
        CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &value));
        value = value-(value>=MCHIP_CAP(SYS_CAP_DOT1AE_TX_CHAN_NUM)?MCHIP_CAP(SYS_CAP_DOT1AE_TX_CHAN_NUM):0);
        cmd = (p_sys_chan->dir == CTC_DOT1AE_SC_DIR_RX)? DRV_IOW(DsMacsecSrcSecYMap_t, DsMacsecSrcSecYMap_secYId_f):
        DRV_IOW(DsMacsecDestSecYMap_t, DsMacsecDestSecYMap_secYId_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, sc_idx, cmd, &value));
    }
    else if (p_sys_chan->binding_type == 2)
    {
        value = p_sys_chan->sc_index[dp_id];
        cmd = DRV_IOW(DsMacsecSrcSecYMap_t, DsMacsecSrcSecYMap_secYId_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, sc_idx, cmd, &value));
    }
    else if (p_sys_chan->binding_type == 1)
    {
        value = p_sys_chan->sc_index[dp_id];
        cmd = DRV_IOW(DsMacsecDestSecYMap_t, DsMacsecDestSecYMap_secYId_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, sc_idx, cmd, &value));
    }
    secYId = sys_tmm_dot1ae_get_secyid(lchip, p_sys_chan->chan_id,dp_id);

    if (p_sys_chan->dir == CTC_DOT1AE_SC_DIR_TX)
    {
        value = p_sys_chan->is_xpn;

        cmd = DRV_IOW(DsMacsecTransmitSc_t, DsMacsecTransmitSc_isXpnMode_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, sc_idx, cmd, &value));

        if (p_sys_chan->sci)
        {
            SYS_USW_SET_HW_VALUE(sci_hw, (uint8*)p_sys_chan->sci, sizeof(sci_hw));
        }
        cmd =  DRV_IOW(DsMacsecTransmitSc_t, DsMacsecTransmitSc_sci_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip,  sc_idx , cmd, &sci_hw));

        value = 1;
        cmd = DRV_IOW(DsMacsecDestSecY_t, DsMacsecDestSecY_controlledPortEnabled_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, secYId, cmd, &value));


        value = p_sys_chan->p2mp;
        cmd = DRV_IOW(DsMacsecDestSecY_t, DsMacsecDestSecY_p2mpSecY_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, secYId, cmd, &value));

        value = 1;
        cmd = DRV_IOW(DsMacsecDestSecY_t, DsMacsecDestSecY_protectFrames_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, secYId, cmd, &value));

        value = SYS_DOT1AE_PACKET_MAX_LENTH;
        cmd = DRV_IOW(DsMacsecDestSecY_t, DsMacsecDestSecY_macsecMaxLen_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, secYId, cmd, &value));

        value = p_sys_chan->include_sci;
        cmd = DRV_IOW(DsMacsecDestSecY_t, DsMacsecDestSecY_alwaysIncludeSci_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, secYId, cmd, &value));

        value = p_sys_chan->macsecType;
        cmd = DRV_IOW(DsMacsecDestSecY_t, DsMacsecDestSecY_macsecType_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, secYId, cmd, &value));

        value = p_sys_chan->sc_index[dp_id];
        cmd = DRV_IOW(DsMacsecDestSecYPre_t, DsMacsecDestSecYPre_transmitScId_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, secYId, cmd, &value));
        value = (p_sys_chan->binding_type || p_sys_chan->p2mp || p_sys_chan->clear_tag_en)? 1 : 0;
        cmd = DRV_IOW(DsMacsecDestSecYPre_t, DsMacsecDestSecYPre_isAdvSecY_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, secYId, cmd, &value));

        if (p_sys_chan->binding_type != 0)
        {
            value = 1;
            cmd = DRV_IOW(DsMacsecDestSecY_t, DsMacsecDestSecY_macsecEnable_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, secYId, cmd, &value));
        }
    }
    else
    {
        value = p_sys_chan->an_valid &0xF;
        cmd = DRV_IOW(DsMacsecReceiveSc_t, DsMacsecReceiveSc_saValid_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, sc_idx, cmd, &value));

        value = p_sys_chan->is_xpn;
        cmd = DRV_IOW(DsMacsecReceiveSc_t, DsMacsecReceiveSc_isXpnMode_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, sc_idx, cmd, &value));
        if (p_sys_chan->sci)
        {
            SYS_USW_SET_HW_VALUE(sci_hw, (uint8*)p_sys_chan->sci, sizeof(sci_hw));
        }
        cmd = DRV_IOW(DsMacsecReceiveSc_t, DsMacsecReceiveSc_sci_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip,  sc_idx , cmd, &sci_hw));

        value = 1;
        cmd = DRV_IOW(DsMacsecSrcSecY_t, DsMacsecSrcSecY_controlledPortEnabled_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, secYId, cmd, &value));

        value = p_sys_chan->validateFrames;
        cmd = DRV_IOW(DsMacsecSrcSecY_t, DsMacsecSrcSecY_validateFrames_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, secYId, cmd, &value));

        value = p_sys_chan->replayProtect;
        cmd = DRV_IOW(DsMacsecSrcSecY_t, DsMacsecSrcSecY_replayProtect_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, secYId, cmd, &value));

        value = 0;
        cmd = DRV_IOW(DsMacsecSrcSecY_t, DsMacsecSrcSecY_discardUncontrolledSecTagPkt_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, secYId, cmd, &value));

        value = 1;
        cmd = DRV_IOW(DsMacsecSrcSecY_t, DsMacsecSrcSecY_discardUnsupportSecTagPkt_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, secYId, cmd, &value));

        value = p_sys_chan->replayProtectWindow;
        cmd = DRV_IOW(DsMacsecSrcSecY_t, DsMacsecSrcSecY_replayProtectWindow_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, secYId, cmd, &value));


        value = p_sys_chan->macsecType;
        cmd = DRV_IOW(DsMacsecSrcSecYPre_t, DsMacsecSrcSecYPre_macsecType_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, secYId, cmd, &value));

        value = p_sys_chan->sc_index[dp_id] ;
        cmd = DRV_IOW(DsMacsecSrcSecYPre_t, DsMacsecSrcSecYPre_receiveScId_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, secYId, cmd, &value));
    }

    return CTC_E_NONE;
}

int32
sys_tmm_dot1ae_add_sc_to_asic(uint8 lchip, void* sys_chan)
{
    sys_dot1ae_chan_t* p_sys_chan = (sys_dot1ae_chan_t*)sys_chan;

    SYS_DOT1AE_FOREACH_DP_BEGIN(p_sys_chan->dp_bmp)
    CTC_ERROR_RETURN(_sys_tmm_dot1ae_add_sc_to_asic(lchip, p_sys_chan,dp_idx));
    SYS_DOT1AE_FOREACH_DP_END

    return CTC_E_NONE;
}

STATIC int32
_sys_tmm_dot1ae_add_sa_to_asic(uint8 lchip, sys_dot1ae_chan_t* p_sys_sec_chan, uint8 sa_idx, uint32 update_flag,uint8 dp_id)
{
    uint32 cmd = 0;
    uint32 value = 0;
    uint32 key_hw[8] = {0};
    uint32 salt_hw[3] ={0};
    uint32 sc_idx = 0;
    uint32 cipher_mode = 0;
    uint32 cipher_suite = p_sys_sec_chan->sa_cfg[sa_idx].cipher_suite;
    uint32 key_index = 0;
    uint32 sa_offst =0;
    uint32 stats_index =0;
    uint32 enableTransmit[8] ={0};
    uint32 encodingSa[4] = {0};
    uint32 val_ary[2]={0};
    uint8 an = 0;
    uint8 key_len = 0;
    uint8 secYId = 0;

    sc_idx = (p_sys_sec_chan->sc_index[dp_id]) + (dp_id? MCHIP_CAP(SYS_CAP_DOT1AE_TX_CHAN_NUM) : 0);
    key_index =  (p_sys_sec_chan->sc_index[dp_id] << 1) + (dp_id? MCHIP_CAP(SYS_CAP_DOT1AE_SEC_CHAN_NUM) : 0) + (sa_idx & 0x1);
    stats_index = (p_sys_sec_chan->sc_index[dp_id] << 1) + (sa_idx & 0x1);

    if (CTC_FLAG_ISSET(update_flag, CTC_DOT1AE_SA_FLAG_ENCRYPTION))
    {
        cipher_mode = p_sys_sec_chan->sa_cfg[sa_idx].cipher_mode;
        if ((p_sys_sec_chan->binding_type != 0)|| p_sys_sec_chan->clear_tag_en)
        {
            if (cipher_mode == 1 || cipher_mode == 2 )
            {
                return CTC_E_INVALID_CONFIG;
            }
            if (cipher_mode == 0)
            {
                cipher_mode = 4;
            }
            else if (cipher_mode == 3)
            {
                cipher_mode = 5;
            }
        }
        cmd = (p_sys_sec_chan->dir == CTC_DOT1AE_SC_DIR_RX)? DRV_IOW(DsMacsecReceiveSa_t, DsMacsecReceiveSa_cipherMode_f):
        DRV_IOW(DsMacsecTransmitSa_t, DsMacsecTransmitSa_cipherMode_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, key_index, cmd, &cipher_mode));
    }

    if (CTC_FLAG_ISSET(update_flag, CTC_DOT1AE_SA_FLAG_NEXT_PN))
    {
        val_ary[0] = p_sys_sec_chan->sa_cfg[sa_idx].next_pn&0xFFFFFFFF;
        val_ary[1] = (p_sys_sec_chan->sa_cfg[sa_idx].next_pn >> 32)&0xFFFFFFFF;
        cmd = (p_sys_sec_chan->dir == CTC_DOT1AE_SC_DIR_TX) ? DRV_IOW(DsMacsecTransmitSaPn_t, DsMacsecTransmitSaPn_macsecPn_f):
        DRV_IOW(DsMacsecReceiveSaStatus_t, DsMacsecReceiveSaStatus_nextPn_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, key_index, cmd, val_ary));
    }


    if (CTC_FLAG_ISSET(update_flag, CTC_DOT1AE_SA_FLAG_KEY))
    {
        key_len = (CTC_DOT1AE_CIPHER_SUITE_GCM_AES_128 == p_sys_sec_chan->sa_cfg[sa_idx].cipher_suite
            || CTC_DOT1AE_CIPHER_SUITE_GCM_AES_XPN_128 == p_sys_sec_chan->sa_cfg[sa_idx].cipher_suite)?(CTC_DOT1AE_KEY_LEN / 2):CTC_DOT1AE_KEY_LEN;
        SYS_USW_SET_HW_VALUE(key_hw, p_sys_sec_chan->sa_cfg[sa_idx].key, key_len);

        cmd = (p_sys_sec_chan->dir == CTC_DOT1AE_SC_DIR_RX)? DRV_IOW(DsMacsecReceiveSa_t, DsMacsecReceiveSa_aesKey_f):
        DRV_IOW(DsMacsecTransmitSa_t, DsMacsecTransmitSa_aesKey_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, key_index, cmd, key_hw));

        SYS_USW_SET_HW_VALUE(salt_hw, p_sys_sec_chan->sa_cfg[sa_idx].salt, sizeof(salt_hw));
        cmd = (p_sys_sec_chan->dir == CTC_DOT1AE_SC_DIR_RX)? DRV_IOW(DsMacsecReceiveSa_t, DsMacsecReceiveSa_salt_f):
        DRV_IOW(DsMacsecTransmitSa_t, DsMacsecTransmitSa_salt_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, key_index, cmd, salt_hw));

        cmd = (p_sys_sec_chan->dir == CTC_DOT1AE_SC_DIR_RX)? DRV_IOW(DsMacsecReceiveSa_t, DsMacsecReceiveSa_ssci_f):
        DRV_IOW(DsMacsecTransmitSa_t, DsMacsecTransmitSa_ssci_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, key_index, cmd, &p_sys_sec_chan->sa_cfg[sa_idx].ssci));

        cmd = (p_sys_sec_chan->dir == CTC_DOT1AE_SC_DIR_RX)?  DRV_IOW(DsMacsecReceiveSa_t, DsMacsecReceiveSa_cipherSuite_f):
        DRV_IOW(DsMacsecTransmitSa_t, DsMacsecTransmitSa_cipherSuite_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, key_index, cmd, &cipher_suite));

        value = p_sys_sec_chan->is_xpn;
        cmd = (p_sys_sec_chan->dir == CTC_DOT1AE_SC_DIR_RX)?  DRV_IOW(DsMacsecReceiveSc_t, DsMacsecReceiveSc_isXpnMode_f):
        DRV_IOW(DsMacsecTransmitSc_t, DsMacsecTransmitSc_isXpnMode_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, sc_idx, cmd, &value));
    }

    if (CTC_FLAG_ISSET(update_flag, CTC_DOT1AE_SA_FLAG_VALIDATEFRAMES))
    {
        secYId = sys_tmm_dot1ae_get_secyid(lchip, p_sys_sec_chan->chan_id,dp_id);
        value = p_sys_sec_chan->validateFrames;
        cmd = DRV_IOW(DsMacsecSrcSecY_t, DsMacsecSrcSecY_validateFrames_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, secYId, cmd, &value));
    }

    an = p_sys_sec_chan->sa_cfg[sa_idx].an;
    value = CTC_IS_BIT_SET(p_sys_sec_chan->an_en, an);
    if (p_sys_sec_chan->dir == CTC_DOT1AE_SC_DIR_RX)
    {
        cmd = DRV_IOW(DsMacsecReceiveSa_t, DsMacsecReceiveSa_enableReceive_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, key_index, cmd, &value));
        val_ary[0] = p_sys_sec_chan->sa_cfg[sa_idx].lowest_pn &0xFFFFFFFF;
        val_ary[1] = (p_sys_sec_chan->sa_cfg[sa_idx].lowest_pn >> 32)&0xFFFFFFFF;
        cmd = DRV_IOW(DsMacsecReceiveSaStatus_t, DsMacsecReceiveSaStatus_lowestPn_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, key_index, cmd, val_ary));

        cmd = DRV_IOR(DsMacsecReceiveScPre_t, DsMacsecReceiveScPre_saOffset_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, sc_idx, cmd, &sa_offst));
        if (sa_idx)
        {
            CTC_BIT_SET(sa_offst, an);
        }
        else if (!sa_idx)
        {
            CTC_BIT_UNSET(sa_offst, an);
        }
        cmd = DRV_IOW(DsMacsecReceiveScPre_t, DsMacsecReceiveScPre_saOffset_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, sc_idx, cmd, &sa_offst));

        value = p_sys_sec_chan->an_valid & 0xF;
        cmd = DRV_IOW(DsMacsecReceiveSc_t, DsMacsecReceiveSc_saValid_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, sc_idx, cmd, &value));
    }
    else
    {
        cmd = DRV_IOR(MacsecTransmitScStatus0_t, MacsecTransmitScStatus0_encodingSa_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, dp_id, cmd, encodingSa));
        if (value && sa_idx)
        {
            DRV_BIT_SET(encodingSa[p_sys_sec_chan->sc_index[dp_id] / 32], p_sys_sec_chan->sc_index[dp_id] % 32);
        }
        else if (value && !sa_idx)
        {
            DRV_BIT_UNSET(encodingSa[p_sys_sec_chan->sc_index[dp_id] / 32], p_sys_sec_chan->sc_index[dp_id] % 32);
        }
        cmd = DRV_IOW(MacsecTransmitScStatus0_t, MacsecTransmitScStatus0_encodingSa_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, dp_id, cmd, encodingSa));

        cmd = DRV_IOR(MacsecTransmitSaStatus_t, MacsecTransmitSaStatus_enableTransmit_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, dp_id, cmd, enableTransmit));
        CTC_BIT_SET(enableTransmit[stats_index / 32], stats_index % 32);
        cmd = DRV_IOW(MacsecTransmitSaStatus_t, MacsecTransmitSaStatus_enableTransmit_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, dp_id, cmd, enableTransmit));

        value = p_sys_sec_chan->sa_cfg[sa_idx].an &0x3;
        cmd = DRV_IOW(DsMacsecTransmitSa_t, DsMacsecTransmitSa_encodingAn_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, key_index, cmd, &value));
    }

    return CTC_E_NONE;
}

int32
sys_tmm_dot1ae_add_sa_to_asic(uint8 lchip, void* sec_chan, uint8 sa_idx, uint32 update_flag)
{
    sys_dot1ae_chan_t* p_sys_chan = (sys_dot1ae_chan_t*)sec_chan;
    SYS_DOT1AE_FOREACH_DP_BEGIN(p_sys_chan->dp_bmp)
    CTC_ERROR_RETURN(_sys_tmm_dot1ae_add_sa_to_asic(lchip, p_sys_chan, sa_idx, update_flag, dp_idx));
    SYS_DOT1AE_FOREACH_DP_END

    return CTC_E_NONE;

}

STATIC int32
_sys_tmm_dot1ae_update_global_pn_mode_traverse(sys_dot1ae_chan_t* p_sys_chan, void* user_data)
{
    sys_traverse_t* traversal_data = (sys_traverse_t *)user_data;
    uint32 value = traversal_data->value1;
    uint8 lchip = traversal_data->value2;
    uint32 cmd =0;
    uint32 sc_idx = 0;
    if (p_sys_chan->pn_mode == CTC_DOT1AE_SC_PN_MODE_NONE)
    {
        SYS_DOT1AE_FOREACH_DP_BEGIN(p_sys_chan->dp_bmp)
        p_sys_chan->is_xpn =  usw_dot1ae_master[lchip]->is_xpn;
        sc_idx = (p_sys_chan->sc_index[dp_idx]) + (dp_idx? MCHIP_CAP(SYS_CAP_DOT1AE_TX_CHAN_NUM) : 0);
        if (p_sys_chan->dir == CTC_DOT1AE_SC_DIR_TX)
        {
            cmd = DRV_IOW(DsMacsecTransmitSc_t, DsMacsecTransmitSc_isXpnMode_f);
        }
        else
        {
            cmd = DRV_IOW(DsMacsecReceiveSc_t, DsMacsecReceiveSc_isXpnMode_f);
        }
        DRV_FIELD_IOCTL(lchip, sc_idx, cmd, &value);
        SYS_DOT1AE_FOREACH_DP_END
    }
    return CTC_E_NONE;
}

STATIC int32
_sys_tmm_dot1ae_update_global_pn_mode(uint8 lchip, uint8 is_xpn)
{
    sys_traverse_t user_data;
    sal_memset(&user_data, 0 ,sizeof(sys_traverse_t));
    user_data.value1 = is_xpn;
    user_data.value2 = lchip;
    CTC_ERROR_RETURN(ctc_hash_traverse(usw_dot1ae_master[lchip]->chan_hash, (hash_traversal_fn)_sys_tmm_dot1ae_update_global_pn_mode_traverse, (void *)&user_data));
    return CTC_E_NONE;
}

STATIC int32
_sys_tmm_dot1ae_update_lowest_pn(uint8 lchip,sys_dot1ae_chan_t* p_sys_chan)
{
    uint8 loop = 0;
    uint32 cmd =0;
    uint32 key_index=0;
    uint64 lowestPn=0;
    uint32 val_ary[2]={0};
    ds_t ds;
    uint64 pn_tmp=0;
    if (p_sys_chan->dir == CTC_DOT1AE_SC_DIR_RX)
    {
        for (loop = 0; loop < 2; loop++)
        {
            if (CTC_SLISTCOUNT(p_sys_chan->bind_mem_list))
            {
                SYS_DOT1AE_FOREACH_DP_BEGIN(p_sys_chan->dp_bmp)
                key_index =  (p_sys_chan->sc_index[dp_idx] << 1) + (dp_idx? MCHIP_CAP(SYS_CAP_DOT1AE_SEC_CHAN_NUM) : 0) + loop;
                cmd = DRV_IOR(DsMacsecReceiveSaStatus_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, key_index, cmd, ds));
                GetDsMacsecReceiveSaStatus(A, nextPn_f, &ds, val_ary);
                pn_tmp = ((uint64)val_ary[1] << 32) | val_ary[0];
                if (p_sys_chan->replayProtect)
                {
                    lowestPn = pn_tmp > p_sys_chan->replayProtectWindow ? pn_tmp - p_sys_chan->replayProtectWindow : 0;
                    p_sys_chan->sa_cfg[loop].lowest_pn = lowestPn;
                    val_ary[0] = lowestPn&0xFFFFFFFF;
                    val_ary[1] = (lowestPn >> 32)&0xFFFFFFFF;
                    cmd = DRV_IOW(DsMacsecReceiveSaStatus_t, DsMacsecReceiveSaStatus_lowestPn_f);
                    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, key_index, cmd, val_ary));
                }
                SYS_DOT1AE_FOREACH_DP_END
            }
            else
            {
                if (p_sys_chan->replayProtect)
                {
                    p_sys_chan->sa_cfg[loop].lowest_pn = p_sys_chan->sa_cfg[loop].next_pn > p_sys_chan->replayProtectWindow ? p_sys_chan->sa_cfg[loop].next_pn - p_sys_chan->replayProtectWindow : 0;
                }
                else
                {
                    p_sys_chan->sa_cfg[loop].lowest_pn = p_sys_chan->sa_cfg[loop].next_pn;
                }
            }
        }
    }
    return CTC_E_NONE;
}

int32
_sys_tmm_lkup_sec_chan_by_port_traverse(sys_dot1ae_chan_t* p_sys_chan,void* user_data)
{
    uint32 gport = 0;
    uint8 dir =0;
    ctc_slistnode_t* node = NULL;
    sys_dot1ae_chan_bind_node_t* p_sec_chan_bind_node = NULL;
    ctc_dot1ae_an_stats_t stats;
    uint8 lchip = 0;
    sys_dot1ae_chan_t* p_chan=NULL;
    sys_traverse_t* traversal_data = (sys_traverse_t *)user_data;
    ctc_dot1ae_an_stats_t*p_stats = (ctc_dot1ae_an_stats_t*)traversal_data->data;
    sys_tmm_dot1ae_an_stats_t* p_sys_stats = (sys_tmm_dot1ae_an_stats_t*)(p_sys_chan->an_stats);
    sal_memset(&stats, 0 , sizeof(ctc_dot1ae_an_stats_t));
    gport = traversal_data->value1;
    dir =  traversal_data->value2;
    lchip = traversal_data->value3;

    if ((dir ==p_sys_chan->dir)&&CTC_SLISTCOUNT(p_sys_chan->bind_mem_list))
    {
        CTC_SLIST_LOOP(p_sys_chan->bind_mem_list, node)
        {
            p_sec_chan_bind_node = _ctc_container_of(node, sys_dot1ae_chan_bind_node_t, head);
            if ((p_sec_chan_bind_node->value == gport) && (!p_sys_chan->binding_type))
            {
                sys_tmm_dot1ae_get_stats(lchip, p_sys_chan->chan_id, &stats);
                p_chan = _sys_usw_dot1ae_chan_lookup(lchip, p_sys_chan->chan_id);
                if (NULL == p_chan)
                {
                    return CTC_E_NOT_EXIST;
                }
                if (((_ctc_container_of(p_sys_chan->bind_mem_list->head, sys_dot1ae_chan_bind_node_t, head))->value ==
                            (_ctc_container_of(p_chan->bind_mem_list->head, sys_dot1ae_chan_bind_node_t, head))->value))
                {
                    if (p_sys_chan->dir == CTC_DOT1AE_SC_DIR_TX)
                    {
                        p_stats->out_pkts_untagged +=  p_sys_stats[0].out_pkts_untagged;
                        p_stats->out_pkts_toolong +=  p_sys_stats[0].out_pkts_toolong;
                        p_stats->out_octets_encrypted +=  p_sys_stats[0].out_octets_encrypted;
                        p_stats->out_octets_protected +=  p_sys_stats[0].out_octets_protected;
                    }
                    else
                    {
                        p_stats->in_pkts_badtag +=  p_sys_stats[0].in_pkts_badtag;
                        p_stats->in_octets_decrypted +=  p_sys_stats[0].in_octets_decrypted;
                        p_stats->in_octets_validated +=  p_sys_stats[0].in_octets_validated;
                        p_stats->in_pkts_not_using_sa += p_sys_stats[0].in_pkts_not_using_sa;
                        p_stats->in_pkts_unused_sa += p_sys_stats[0].in_pkts_unused_sa;
                    }
                }
            }
        }
    }
     return CTC_E_NONE;
}

#define __SYS_INTERFACE__

int32
sys_tmm_dot1ae_chan_wb_restore(uint8 lchip, void* p_chan)
{
    ds_t ds;
    uint32 val_ary[2]={0};
    uint32  salt_hw[3]={0};
    uint32 cmd = 0;
    uint8 hw_sci[SYS_DOT1AE_SCI_LEN]={0};
    uint16 key_index = 0;
    uint16 secYId = 0;
    uint8* p_key_hw = NULL;
    sys_usw_opf_t opf;
    uint8 sa_idx = 0;

    sys_dot1ae_chan_t* p_sys_chan = (sys_dot1ae_chan_t*)p_chan;

    SYS_DOT1AE_FOREACH_DP_BEGIN(p_sys_chan->dp_bmp)
    key_index = p_sys_chan->sc_index[dp_idx];
    if (p_sys_chan->dir == CTC_DOT1AE_SC_DIR_TX)
    {
        cmd = DRV_IOR(DsMacsecTransmitSc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip,  key_index , cmd, &ds));
        GetDsMacsecTransmitSc(A, sci_f, &ds,hw_sci);
        SYS_USW_SET_USER_VALUE(p_sys_chan->sci, (uint32*)hw_sci, SYS_DOT1AE_SCI_LEN);
    }
    else
    {
        cmd = DRV_IOR(DsMacsecReceiveSc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip,  key_index , cmd, &ds));
        GetDsMacsecReceiveSc(A, sci_f, &ds,hw_sci);
        SYS_USW_SET_USER_VALUE(p_sys_chan->sci, (uint32*)hw_sci, SYS_DOT1AE_SCI_LEN);

        secYId = sys_tmm_dot1ae_get_secyid(lchip, p_sys_chan->chan_id, dp_idx);
        cmd = DRV_IOR(DsMacsecSrcSecY_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, secYId, cmd, &ds));
        p_sys_chan->validateFrames = GetDsMacsecSrcSecY(V, validateFrames_f, &ds);
        p_sys_chan->replayProtect = GetDsMacsecSrcSecY(V, replayProtect_f, &ds);
        p_sys_chan->replayProtectWindow = GetDsMacsecSrcSecY(V, replayProtectWindow_f, &ds);
    }

    for (sa_idx = 0; sa_idx < 2; sa_idx++)
    {
        key_index = (p_sys_chan->sc_index[dp_idx] << 1) + (sa_idx & 0x1) + (dp_idx? MCHIP_CAP(SYS_CAP_DOT1AE_SEC_CHAN_NUM) : 0);
        cmd = (p_sys_chan->dir == CTC_DOT1AE_SC_DIR_TX) ? DRV_IOR(DsMacsecTransmitSaPn_t, DRV_ENTRY_FLAG) : DRV_IOR(DsMacsecReceiveSaStatus_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, key_index, cmd, &ds));
        if (p_sys_chan->dir == CTC_DOT1AE_SC_DIR_TX)
        {
            GetDsMacsecTransmitSaPn(A, macsecPn_f, &ds, val_ary);
        }
        else
        {
            GetDsMacsecReceiveSaStatus(A, nextPn_f, &ds, val_ary);
        }
    
        p_sys_chan->sa_cfg[sa_idx].next_pn = ((uint64)val_ary[1] << 32) | val_ary[0];
        if (p_sys_chan->dir == CTC_DOT1AE_SC_DIR_RX)
        {
            if (p_sys_chan->replayProtect)
            {
                if (p_sys_chan->sa_cfg[sa_idx].next_pn > p_sys_chan->replayProtectWindow)
                {
                    p_sys_chan->sa_cfg[sa_idx].lowest_pn = p_sys_chan->sa_cfg[sa_idx].next_pn - p_sys_chan->replayProtectWindow;
                }
            }
            else
            {
                p_sys_chan->sa_cfg[sa_idx].lowest_pn = p_sys_chan->sa_cfg[sa_idx].next_pn;
            }
        }
        cmd = (p_sys_chan->dir == CTC_DOT1AE_SC_DIR_RX)? DRV_IOR(DsMacsecReceiveSa_t, DRV_ENTRY_FLAG):
        DRV_IOR(DsMacsecTransmitSa_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, key_index, cmd, &ds));
        if (p_sys_chan->dir == CTC_DOT1AE_SC_DIR_RX)
        {
            p_sys_chan->sa_cfg[sa_idx].cipher_mode = GetDsMacsecReceiveSa(V, cipherMode_f, &ds);
            p_sys_chan->sa_cfg[sa_idx].cipher_suite = GetDsMacsecReceiveSa(V, cipherSuite_f, &ds);
            sal_memset(salt_hw, 0, sizeof(salt_hw));
            GetDsMacsecReceiveSa(A, salt_f, &ds, salt_hw);
            SYS_USW_SET_USER_VALUE(p_sys_chan->sa_cfg[sa_idx].salt, salt_hw, sizeof(salt_hw));
            p_sys_chan->sa_cfg[sa_idx].ssci = GetDsMacsecReceiveSa(V, ssci_f, &ds);
            p_key_hw = mem_malloc(MEM_DOT1AE_MODULE, CTC_DOT1AE_KEY_LEN);
            if (NULL == p_key_hw)
            {
                return CTC_E_NO_MEMORY;
            }
            sal_memset(p_key_hw, 0 , CTC_DOT1AE_KEY_LEN);
            if ((CTC_DOT1AE_CIPHER_SUITE_GCM_AES_128 == p_sys_chan->sa_cfg[sa_idx].cipher_suite) || (CTC_DOT1AE_CIPHER_SUITE_GCM_AES_XPN_128 == p_sys_chan->sa_cfg[sa_idx].cipher_suite))
            {
                GetDsMacsecReceiveSa(A, aesKey_f, &ds, p_key_hw);
                SYS_USW_SET_USER_VALUE(p_sys_chan->sa_cfg[sa_idx].key, (uint32*)p_key_hw, CTC_DOT1AE_KEY_LEN / 2);
            }
            else
            {
                GetDsMacsecReceiveSa(A, aesKey_f, &ds, p_key_hw);
                SYS_USW_SET_USER_VALUE(p_sys_chan->sa_cfg[sa_idx].key, (uint32*)p_key_hw, CTC_DOT1AE_KEY_LEN);
            }
            mem_free(p_key_hw);
        }
        else
        {
            sal_memset(salt_hw, 0, sizeof(salt_hw));
            p_sys_chan->sa_cfg[sa_idx].cipher_mode = GetDsMacsecTransmitSa(V, cipherMode_f, &ds);
            p_sys_chan->sa_cfg[sa_idx].cipher_suite = GetDsMacsecTransmitSa(V, cipherSuite_f, &ds);
            GetDsMacsecTransmitSa(A, salt_f, &ds, salt_hw);
            SYS_USW_SET_USER_VALUE(p_sys_chan->sa_cfg[sa_idx].salt, salt_hw, sizeof(salt_hw));
            p_sys_chan->sa_cfg[sa_idx].ssci = GetDsMacsecTransmitSa(V, ssci_f, &ds);
            p_key_hw = mem_malloc(MEM_DOT1AE_MODULE, CTC_DOT1AE_KEY_LEN);
            if (NULL == p_key_hw)
            {
                return CTC_E_NO_MEMORY;
            }
            sal_memset(p_key_hw, 0 , CTC_DOT1AE_KEY_LEN);
            if ((CTC_DOT1AE_CIPHER_SUITE_GCM_AES_128 == p_sys_chan->sa_cfg[sa_idx].cipher_suite) || (CTC_DOT1AE_CIPHER_SUITE_GCM_AES_XPN_128 == p_sys_chan->sa_cfg[sa_idx].cipher_suite))
            {
                GetDsMacsecTransmitSa(A, aesKey_f, &ds, p_key_hw);
                SYS_USW_SET_USER_VALUE(p_sys_chan->sa_cfg[sa_idx].key, (uint32*)p_key_hw, CTC_DOT1AE_KEY_LEN / 2);
            }
            else
            {
                GetDsMacsecTransmitSa(A, aesKey_f, &ds, p_key_hw);
                SYS_USW_SET_USER_VALUE(p_sys_chan->sa_cfg[sa_idx].key, (uint32*)p_key_hw, CTC_DOT1AE_KEY_LEN);
            }
            mem_free(p_key_hw);
        }
        if (0 != p_sys_chan->binding_type)
        {
            p_sys_chan->sa_cfg[sa_idx].no_encryption = (p_sys_chan->sa_cfg[sa_idx].cipher_mode == 5 )? 1 : 0;
        }
        else
        {
            p_sys_chan->sa_cfg[sa_idx].no_encryption = (p_sys_chan->sa_cfg[sa_idx].cipher_mode == 3 )? 1 : 0;
        }
    }
     sal_memset(&opf,0,sizeof(sys_usw_opf_t));
    if (p_sys_chan->binded || CTC_SLISTCOUNT(p_sys_chan->bind_mem_list))
    {
        opf.pool_type = usw_dot1ae_master[lchip]->dot1ae_opf_type;
        opf.pool_index = ((p_sys_chan->dir == CTC_DOT1AE_SC_DIR_TX) ? 0 : 1) + (dp_idx? 2 : 0);
        CTC_ERROR_RETURN(sys_usw_opf_alloc_offset_from_position(lchip, &opf, 1, p_sys_chan->sc_index[dp_idx]));
    }
    SYS_DOT1AE_FOREACH_DP_END

    return CTC_E_NONE;
}

int32
sys_tmm_dot1ae_set_glb_cfg(uint8 lchip, void* glb_cfg)
{
    uint32 cmd   = 0;
    uint32 val_ary[2] = {0};
    ctc_dot1ae_glb_cfg_t* p_glb_cfg = (ctc_dot1ae_glb_cfg_t*)glb_cfg;

    SYS_DOT1AE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n",__FUNCTION__);

    CTC_ERROR_RETURN(_sys_tmm_dot1ae_update_global_pn_mode(lchip,usw_dot1ae_master[lchip]->is_xpn));

    val_ary[0] = p_glb_cfg->tx_xpn_thrd&0xFFFFFFFF;
    val_ary[1] = (p_glb_cfg->tx_xpn_thrd >> 32)&0xFFFFFFFF;
    cmd = DRV_IOW(MacsecTxCtl_t, MacsecTxCtl_xpnThreshold0_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, val_ary));

    val_ary[0] = p_glb_cfg->rx_xpn_thrd&0xFFFFFFFF;
    val_ary[1] = (p_glb_cfg->rx_xpn_thrd >> 32)&0xFFFFFFFF;
    cmd = DRV_IOW(MacsecRxCtl_t, MacsecRxCtl_xpnThreshold0_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, val_ary));

    val_ary[0] = p_glb_cfg->tx_pn_thrd&0xFFFFFFFF;
    cmd = DRV_IOW(MacsecTxCtl_t, MacsecTxCtl_pnThreshold0_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, val_ary));

    val_ary[0] = p_glb_cfg->rx_pn_thrd&0xFFFFFFFF;
    cmd = DRV_IOW(MacsecRxCtl_t, MacsecRxCtl_pnThreshold0_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, val_ary));

    if(p_glb_cfg->tx_pn_overflow_action)
    {
        return CTC_E_NOT_SUPPORT;
    }

    return CTC_E_NONE;
}

int32
sys_tmm_dot1ae_get_glb_cfg(uint8 lchip, void* glb_cfg)
{    
    uint32 cmd   = 0;
    uint32 val_ary[2] = {0};
    ctc_dot1ae_glb_cfg_t* p_glb_cfg = (ctc_dot1ae_glb_cfg_t*)glb_cfg;

    SYS_DOT1AE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n",__FUNCTION__);
    p_glb_cfg->is_xpn = usw_dot1ae_master[lchip]->is_xpn;

    cmd = DRV_IOR(MacsecTxCtl_t, MacsecTxCtl_xpnThreshold0_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, val_ary));
    p_glb_cfg->tx_xpn_thrd = ((uint64)val_ary[1]<<32) | val_ary[0];
    cmd = DRV_IOR(MacsecRxCtl_t, MacsecRxCtl_xpnThreshold0_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, val_ary));
    p_glb_cfg->rx_xpn_thrd = ((uint64)val_ary[1]<<32) | val_ary[0];

    sal_memset(val_ary, 0, sizeof(val_ary));
    cmd = DRV_IOR(MacsecTxCtl_t, MacsecTxCtl_pnThreshold0_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, val_ary));
    p_glb_cfg->tx_pn_thrd = ((uint64)val_ary[1]<<32) | val_ary[0];
    cmd = DRV_IOR(MacsecRxCtl_t, MacsecRxCtl_pnThreshold0_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, val_ary));
    p_glb_cfg->rx_pn_thrd = ((uint64)val_ary[1]<<32) | val_ary[0];

    return CTC_E_NONE;
}


int32
sys_tmm_dot1ae_update_sec_chan(uint8 lchip, void* sys_chan, void* sc)
{
    sys_dot1ae_chan_t* p_sys_sec_chan = (sys_dot1ae_chan_t*)sys_chan;
    ctc_dot1ae_sc_t* p_sc = (ctc_dot1ae_sc_t*)sc;
    int32  ret = CTC_E_NONE;
    uint32 cmd = 0;
    uint32 sci_hw[2] = {0};
    uint32 value =0;
    uint32 sc_idx =0;
    uint16 secYId = 0;

    SYS_DOT1AE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    switch(p_sc->property)
    {
    case CTC_DOT1AE_SC_PROP_AN_EN:  
        /**< [D2][tx/rx] Enable AN to channel  */
        p_sys_sec_chan->an_en = p_sc->data&0xF;
        SYS_DOT1AE_FOREACH_DP_BEGIN(p_sys_sec_chan->dp_bmp)
        ret = _sys_tmm_dot1ae_update_sec_chan_an_en(lchip,p_sys_sec_chan, p_sc->data,dp_idx);
        SYS_DOT1AE_FOREACH_DP_END
        break;
    case CTC_DOT1AE_SC_PROP_INCLUDE_SCI:
        p_sys_sec_chan->include_sci=  p_sc->data ? 1: 0;

        if (CTC_SLISTCOUNT(p_sys_sec_chan->bind_mem_list))
        {
            value =  p_sc->data;
            SYS_DOT1AE_FOREACH_DP_BEGIN(p_sys_sec_chan->dp_bmp)
            secYId = sys_tmm_dot1ae_get_secyid(lchip, p_sys_sec_chan->chan_id,dp_idx);
            cmd = DRV_IOW(DsMacsecDestSecY_t, DsMacsecDestSecY_alwaysIncludeSci_f);
            CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, secYId, cmd, &value), ret, error_proc);
            SYS_DOT1AE_FOREACH_DP_END
            
        }
        break;
    case CTC_DOT1AE_SC_PROP_SCI :
        SYS_USW_SET_HW_VALUE(sci_hw, (uint8*)p_sc->ext_data, sizeof(sci_hw));
        if (p_sys_sec_chan->p2mp && CTC_SLISTCOUNT(p_sys_sec_chan->bind_mem_list))
        {
            return CTC_E_IN_USE;  /**< [TMM]  [p2mp] SCI not support update after binding for p2mp mode*/
        }
        else if (CTC_SLISTCOUNT(p_sys_sec_chan->bind_mem_list))
        {
            SYS_DOT1AE_FOREACH_DP_BEGIN(p_sys_sec_chan->dp_bmp)
            sc_idx = (p_sys_sec_chan->sc_index[dp_idx]) + (dp_idx? MCHIP_CAP(SYS_CAP_DOT1AE_TX_CHAN_NUM) : 0);
            cmd = (p_sys_sec_chan->dir == CTC_DOT1AE_SC_DIR_RX) ? DRV_IOW(DsMacsecReceiveSc_t, DsMacsecReceiveSc_sci_f) : DRV_IOW(DsMacsecTransmitSc_t, DsMacsecTransmitSc_sci_f);
            CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip,  sc_idx , cmd, &sci_hw), ret, error_proc);
            SYS_DOT1AE_FOREACH_DP_END
            
        }
        if (p_sys_sec_chan->sci)
        {
            sal_memcpy(p_sys_sec_chan->sci, (uint8*)p_sc->ext_data, SYS_DOT1AE_SCI_LEN);
        }
        break;
    case CTC_DOT1AE_SC_PROP_REPLAY_WINDOW_SIZE :
        p_sys_sec_chan->replayProtectWindow = p_sc->data;
        _sys_tmm_dot1ae_update_lowest_pn(lchip,p_sys_sec_chan);
        if (CTC_SLISTCOUNT(p_sys_sec_chan->bind_mem_list))
        {
            SYS_DOT1AE_FOREACH_DP_BEGIN(p_sys_sec_chan->dp_bmp)
            secYId = sys_tmm_dot1ae_get_secyid(lchip, p_sys_sec_chan->chan_id,dp_idx);
            value = p_sys_sec_chan->replayProtectWindow;
            cmd = DRV_IOW(DsMacsecSrcSecY_t, DsMacsecSrcSecY_replayProtectWindow_f);
            CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, secYId, cmd, &value), ret, error_proc);
            SYS_DOT1AE_FOREACH_DP_END
        }
        break;
    case CTC_DOT1AE_SC_PROP_REPLAY_PROTECT_EN:
        p_sys_sec_chan->replayProtect = p_sc->data? 1 : 0;
         _sys_tmm_dot1ae_update_lowest_pn(lchip,p_sys_sec_chan);
        if (CTC_SLISTCOUNT(p_sys_sec_chan->bind_mem_list))
        {
            SYS_DOT1AE_FOREACH_DP_BEGIN(p_sys_sec_chan->dp_bmp)
            secYId = sys_tmm_dot1ae_get_secyid(lchip, p_sys_sec_chan->chan_id,dp_idx);
            value = p_sys_sec_chan->replayProtect;
            cmd = DRV_IOW(DsMacsecSrcSecY_t, DsMacsecSrcSecY_replayProtect_f);
            CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, secYId, cmd, &value), ret, error_proc);
            SYS_DOT1AE_FOREACH_DP_END
        }
        break;
    default :
        break;
     }
    
error_proc:
    return ret;
}

 int32
sys_tmm_dot1ae_get_secyid(uint8 lchip, uint32  chan_id,uint8 dp_id)
{
    uint32 cmd = 0;
    uint32 secYId = 0;
    uint32 sc_idx =0;
    sys_dot1ae_chan_t* p_sys_sec_chan = NULL;
    sys_usw_dmps_port_info_t dmps_port_info = {0};
    SYS_DOT1AE_INIT_CHECK(lchip);
    p_sys_sec_chan = _sys_usw_dot1ae_chan_lookup(lchip, chan_id);
    if (!p_sys_sec_chan)
    {
        return CTC_E_NOT_EXIST;
    }
    sc_idx = p_sys_sec_chan->sc_index[dp_id]+(dp_id?MCHIP_CAP(SYS_CAP_DOT1AE_TX_CHAN_NUM):0);

    if (p_sys_sec_chan->p2mp || p_sys_sec_chan->clear_tag_en || p_sys_sec_chan->binding_type)
    {
        cmd = (p_sys_sec_chan->dir == CTC_DOT1AE_SC_DIR_TX)? DRV_IOR(DsMacsecDestSecYMap_t, DsMacsecDestSecYMap_secYId_f)
        : DRV_IOR(DsMacsecSrcSecYMap_t, DsMacsecSrcSecYMap_secYId_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, sc_idx, cmd, &secYId));
        secYId = secYId + (dp_id? MCHIP_CAP(SYS_CAP_DOT1AE_TX_CHAN_NUM) : 0);
    }
    else
    {
        _sys_tmm_dot1ae_sec_chan_lkup_port(lchip, 0, &dmps_port_info.gport, p_sys_sec_chan);
        CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &secYId));
    }

    return secYId;
}

int32
sys_tmm_dot1ae_unbind_sec_chan(uint8 lchip, void* bind_sc)
{
    sys_traverse_t user_data;
    sal_memset(&user_data, 0 , sizeof(sys_traverse_t));
    user_data.data =  (void*)bind_sc;
    user_data.value1 = lchip;
    CTC_ERROR_RETURN(ctc_hash_traverse(usw_dot1ae_master[lchip]->chan_hash, (hash_traversal_fn)_sys_tmm_dot1ae_unbind_traverse, (void *)&user_data));
    return CTC_E_NONE;
}


int32
sys_tmm_dot1ae_get_en_sec_chan(uint8 lchip, void* bind_sc)
{
    uint8 found = 0;
    sys_dot1ae_chan_t* p_sys_chan = NULL;
    sys_com_dot1ae_bind_sc_t* p_bind_sc =NULL;
    uint32 cmd = 0;
    uint32 value = 0;
    uint16 secYId = 0;
    int32 ret =0;
    uint32 dot1ae_en[4] = {0};
    sys_traverse_t user_data;
    
    p_bind_sc = (sys_com_dot1ae_bind_sc_t*)bind_sc;
    SYS_DOT1AE_INIT_CHECK(lchip);
    if (!SYS_GPORT_IS_NETWORK_PORT(p_bind_sc->gport) || SYS_USW_DOT1AE_GPORT_IS_REMOTE(lchip, p_bind_sc->gport))
    {
        return CTC_E_INVALID_CONFIG;
    }
    SYS_DOT1AE_LOCK(lchip);    
    sal_memset(&user_data, 0 ,sizeof(sys_traverse_t));
    user_data.data =  (void*)p_bind_sc;
    ret = ctc_hash_traverse(usw_dot1ae_master[lchip]->chan_hash, (hash_traversal_fn)_sys_tmm_dot1ae_get_chan_traverse, (void *)&user_data);
    if (ret == - 2)
    {
        found = 1;
    }
    if (found)
    {
        p_sys_chan = _sys_usw_dot1ae_chan_lookup(lchip, user_data.value2);
        if (!p_sys_chan)
        {
            SYS_DOT1AE_UNLOCK(lchip);
            return CTC_E_NOT_EXIST;
        }
        SYS_DOT1AE_FOREACH_DP_BEGIN(p_sys_chan->dp_bmp)
        p_bind_sc->sc_index = p_sys_chan->sc_index[dp_idx];
        if (p_sys_chan->binding_type == 2 || p_sys_chan->p2mp ||p_sys_chan->clear_tag_en)
        {
            p_bind_sc->enable = p_sys_chan->enable;
        }
        else if ((!p_sys_chan->p2mp) && (p_bind_sc->dir == CTC_DOT1AE_SC_DIR_RX)&&(!p_sys_chan->binding_type))
        {
            sal_memset(dot1ae_en, 0, sizeof(dot1ae_en));
            secYId = sys_tmm_dot1ae_get_secyid(lchip, p_sys_chan->chan_id,dp_idx);
            secYId = secYId -( dp_idx? MCHIP_CAP(SYS_CAP_DOT1AE_TX_CHAN_NUM) : 0);
            cmd = DRV_IOR(DsMacsecSrcChannel_t, DsMacsecSrcChannel_p2pMacsecEnable_f);
            CTC_ERROR_RETURN_WITH_UNLOCK(DRV_FIELD_IOCTL(lchip, dp_idx, cmd, dot1ae_en), usw_dot1ae_master[lchip]->sec_mutex);
            p_bind_sc->enable = CTC_IS_BIT_SET(dot1ae_en[secYId / 32], secYId % 32)? 1 : 0;
        }
        else
        {
            secYId = sys_tmm_dot1ae_get_secyid(lchip, p_sys_chan->chan_id,dp_idx);
            cmd = DRV_IOR(DsMacsecDestSecY_t, DsMacsecDestSecY_macsecEnable_f);
            CTC_ERROR_RETURN_WITH_UNLOCK(DRV_FIELD_IOCTL(lchip, secYId, cmd, &value), usw_dot1ae_master[lchip]->sec_mutex);
            p_bind_sc->enable = value;
        }
        SYS_DOT1AE_FOREACH_DP_END
    }
    else
    {
        p_bind_sc->enable = 0;
    }
    SYS_DOT1AE_UNLOCK(lchip);
    return CTC_E_NONE;
}

int32
sys_tmm_dot1ae_en_sec_chan(uint8 lchip, void* bind_sc)
{
    sys_dot1ae_chan_t* p_sys_chan = NULL;
    uint32 cmd = 0;
    uint32 value = 0;
    uint16 secYId = 0;
    int32 ret =0;
    sys_traverse_t user_data;
    uint32 dot1ae_en[4] = {0};
    sys_com_dot1ae_bind_sc_t* p_bind_sc = NULL;
    p_bind_sc = (sys_com_dot1ae_bind_sc_t*)bind_sc;

    SYS_DOT1AE_INIT_CHECK(lchip);
    if (!SYS_GPORT_IS_NETWORK_PORT(p_bind_sc->gport)|| SYS_USW_DOT1AE_GPORT_IS_REMOTE(lchip,p_bind_sc->gport))
    {
        return CTC_E_INVALID_CONFIG;
    }
    SYS_DOT1AE_LOCK(lchip);

    sal_memset(&user_data, 0 ,sizeof(sys_traverse_t));

    user_data.data =  (void*)p_bind_sc;

    ret = ctc_hash_traverse(usw_dot1ae_master[lchip]->chan_hash, (hash_traversal_fn)_sys_tmm_dot1ae_get_chan_traverse, (void *)&user_data);
    if (ret != - 2)
    {
        SYS_DOT1AE_UNLOCK(lchip);
        return CTC_E_NOT_READY;
    }
    p_sys_chan = _sys_usw_dot1ae_chan_lookup(lchip, user_data.value2);
    if (!p_sys_chan)
    {
        SYS_DOT1AE_UNLOCK(lchip);
        return CTC_E_NOT_EXIST;
    }
    CTC_ERROR_RETURN_WITH_UNLOCK(ctc_hash_traverse(usw_dot1ae_master[lchip]->chan_hash, (hash_traversal_fn)_sys_tmm_dot1ae_p2mp_en_sec_chan, (void *)&user_data),
                                 usw_dot1ae_master[lchip]->sec_mutex);

    SYS_DOT1AE_FOREACH_DP_BEGIN(p_sys_chan->dp_bmp)
    if ((p_sys_chan->dir == CTC_DOT1AE_SC_DIR_RX) && (!p_sys_chan->p2mp)&&(!p_sys_chan->binding_type)&& (!p_sys_chan->clear_tag_en))
    {
        sal_memset(dot1ae_en, 0, sizeof(dot1ae_en));
        secYId = sys_tmm_dot1ae_get_secyid(lchip, user_data.value2,dp_idx);
        secYId = dp_idx? (secYId - MCHIP_CAP(SYS_CAP_DOT1AE_TX_CHAN_NUM)) : secYId;
        cmd = DRV_IOR(DsMacsecSrcChannel_t, DsMacsecSrcChannel_p2pMacsecEnable_f);
        CTC_ERROR_RETURN_WITH_UNLOCK(DRV_FIELD_IOCTL(lchip, dp_idx, cmd, dot1ae_en), usw_dot1ae_master[lchip]->sec_mutex);
        if (p_bind_sc->dot1AE_RX_En)   /* enable */
        {
            CTC_BIT_SET(dot1ae_en[secYId / 32], secYId % 32);
        }
        else
        {
            CTC_BIT_UNSET(dot1ae_en[secYId / 32], secYId % 32);
        }
        cmd = DRV_IOW(DsMacsecSrcChannel_t, DsMacsecSrcChannel_p2pMacsecEnable_f);
        CTC_ERROR_RETURN_WITH_UNLOCK(DRV_FIELD_IOCTL(lchip, dp_idx, cmd, dot1ae_en), usw_dot1ae_master[lchip]->sec_mutex);
    }
    else if (p_sys_chan->dir == CTC_DOT1AE_SC_DIR_TX)
    {

        secYId = sys_tmm_dot1ae_get_secyid(lchip, user_data.value2,dp_idx);
        value = p_bind_sc->dot1AE_TX_En;
        cmd = DRV_IOW(DsMacsecDestSecY_t, DsMacsecDestSecY_macsecEnable_f);
        CTC_ERROR_RETURN_WITH_UNLOCK(DRV_FIELD_IOCTL(lchip, secYId, cmd, &value), usw_dot1ae_master[lchip]->sec_mutex);
    }
    SYS_DOT1AE_FOREACH_DP_END

    SYS_DOT1AE_UNLOCK(lchip);
    return CTC_E_NONE;
}


int32
sys_tmm_dot1ae_get_stats(uint8 lchip, uint32 chan_id, void* stats)
{
    uint16 secYId = 0;
    uint32  cmd = 0;
    sys_dot1ae_chan_t* p_chan = NULL;
    uint32 sc_index =0;
    uint32 val_ary[2]={0};
    /*TMM Rx Stats*/
    DsMacsecSecYStats_m rx_SecY;
    DsMacsecScStats_m rx_Sc;
    DsMacsecSecYByteStats_m rx_SecYByte;

    /*TMM Tx Stats*/
    DsMacsecDestSecYStats_m tx_SecY;
    DsMacsecTransmitScStats_m tx_Sc;
    DsMacsecDestSecYByteStats_m tx_SecYByte;
    ctc_dot1ae_stats_t* p_stats = (ctc_dot1ae_stats_t*)stats;
    sys_tmm_dot1ae_an_stats_t* p_sys_stats = NULL;
    SYS_DOT1AE_INIT_CHECK(lchip);
    p_chan = _sys_usw_dot1ae_chan_lookup(lchip, chan_id);
    if (p_chan == NULL)
    {
        return CTC_E_NOT_EXIST;
    }
    SYS_DOT1AE_FOREACH_DP_BEGIN(p_chan->dp_bmp)
    secYId = sys_tmm_dot1ae_get_secyid(lchip, chan_id,dp_idx);
    sc_index = p_chan->sc_index[dp_idx] + (dp_idx? MCHIP_CAP(SYS_CAP_DOT1AE_TX_CHAN_NUM) : 0);

    if (p_chan->dir == CTC_DOT1AE_SC_DIR_RX )
    {

        sal_memset(&rx_SecY, 0, sizeof(rx_SecY));
        cmd = DRV_IOR(DsMacsecSecYStats_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, secYId, cmd, &rx_SecY));
        p_stats->an_stats[0].in_pkts_badtag += GetDsMacsecSecYStats(V, array_0_packetCount_f, &rx_SecY);
        p_stats->an_stats[0].in_pkts_not_using_sa +=  GetDsMacsecSecYStats(V, array_1_packetCount_f, &rx_SecY);
        p_stats->an_stats[0].in_pkts_unused_sa +=  GetDsMacsecSecYStats(V, array_2_packetCount_f, &rx_SecY);

        if (1 == SDK_WORK_PLATFORM)
        {
            sal_memset(&rx_SecY, 0, sizeof(rx_SecY));
            cmd = DRV_IOW(DsMacsecSecYStats_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, secYId, cmd, &rx_SecY));
        }
        sal_memset(&rx_Sc, 0, sizeof(rx_Sc));
        cmd = DRV_IOR(DsMacsecScStats_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_index, cmd, &rx_Sc));
        p_stats->an_stats[0].in_pkts_ok +=  GetDsMacsecScStats(V, array_0_packetCount_f, &rx_Sc);
        p_stats->an_stats[0].in_pkts_unchecked +=  GetDsMacsecScStats(V, array_1_packetCount_f, &rx_Sc);
        p_stats->an_stats[0].in_pkts_delayed +=  GetDsMacsecScStats(V, array_2_packetCount_f, &rx_Sc);
        p_stats->an_stats[0].in_pkts_late +=  GetDsMacsecScStats(V, array_3_packetCount_f, &rx_Sc);
        p_stats->an_stats[0].in_pkts_invalid +=  GetDsMacsecScStats(V, array_4_packetCount_f, &rx_Sc);
        p_stats->an_stats[0].in_pkts_not_valid +=  GetDsMacsecScStats(V, array_5_packetCount_f, &rx_Sc);
        if (1 == SDK_WORK_PLATFORM)
        {
            sal_memset(&rx_Sc, 0, sizeof(rx_Sc));
            cmd = DRV_IOW(DsMacsecScStats_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_index, cmd, &rx_Sc));
        }
        sal_memset(&rx_SecYByte, 0, sizeof(rx_SecYByte));
        cmd = DRV_IOR(DsMacsecSecYByteStats_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, secYId, cmd, &rx_SecYByte));

        sal_memset(val_ary, 0, sizeof(val_ary));
        GetDsMacsecSecYByteStats(A, array_0_byteCount_f, &rx_SecYByte, val_ary);
        p_stats->an_stats[0].in_octets_decrypted += ((uint64)val_ary[1] << 32) | val_ary[0];
        sal_memset(val_ary, 0, sizeof(val_ary));
        GetDsMacsecSecYByteStats(A, array_1_byteCount_f, &rx_SecYByte, val_ary);
        p_stats->an_stats[0].in_octets_validated += ((uint64)val_ary[1] << 32) | val_ary[0];

        if (1 == SDK_WORK_PLATFORM)
        {
            sal_memset(&rx_SecYByte, 0, sizeof(rx_SecYByte));
            cmd = DRV_IOW(DsMacsecSecYByteStats_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, secYId, cmd, &rx_SecYByte));
        }
    }
    else
    {
        sal_memset(&tx_SecY, 0, sizeof(tx_SecY));
        cmd = DRV_IOR(DsMacsecDestSecYStats_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, secYId, cmd, &tx_SecY));
        p_stats->an_stats[0].out_pkts_untagged += GetDsMacsecDestSecYStats(V, array_0_packetCount_f, &tx_SecY);
        p_stats->an_stats[0].out_pkts_toolong +=  GetDsMacsecDestSecYStats(V, array_1_packetCount_f, &tx_SecY);
        if (1 == SDK_WORK_PLATFORM)
        {
            sal_memset(&tx_SecY, 0, sizeof(tx_SecY));
            cmd = DRV_IOW(DsMacsecDestSecYStats_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, secYId, cmd, &tx_SecY));
        }
        sal_memset(&tx_Sc, 0, sizeof(tx_Sc));
        cmd = DRV_IOR(DsMacsecTransmitScStats_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_index, cmd, &tx_Sc));
        p_stats->an_stats[0].out_pkts_encrypted += GetDsMacsecTransmitScStats(V, array_0_packetCount_f, &tx_Sc);
        p_stats->an_stats[0].out_pkts_protected +=  GetDsMacsecTransmitScStats(V, array_1_packetCount_f, &tx_Sc);
        p_stats->an_stats[0].out_pkts_sa_not_inuse +=  GetDsMacsecTransmitScStats(V, array_2_packetCount_f, &tx_Sc);
        if (1 == SDK_WORK_PLATFORM)
        {
            sal_memset(&tx_Sc, 0, sizeof(tx_Sc));
            cmd = DRV_IOW(DsMacsecTransmitScStats_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, sc_index, cmd, &tx_Sc));
        }
        sal_memset(&tx_SecYByte, 0, sizeof(tx_SecYByte));
        cmd = DRV_IOR(DsMacsecDestSecYByteStats_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, secYId, cmd, &tx_SecYByte));

        sal_memset(val_ary, 0, sizeof(val_ary));
        GetDsMacsecDestSecYByteStats(A, array_0_byteCount_f, &tx_SecYByte, val_ary);
        p_stats->an_stats[0].out_octets_encrypted += ((uint64)val_ary[1] << 32) | val_ary[0];
        sal_memset(val_ary, 0, sizeof(val_ary));
        GetDsMacsecDestSecYByteStats(A, array_1_byteCount_f, &tx_SecYByte, val_ary);
        p_stats->an_stats[0].out_octets_protected += ((uint64)val_ary[1] << 32) | val_ary[0];

        if (1 == SDK_WORK_PLATFORM)
        {
            sal_memset(&tx_SecYByte, 0, sizeof(tx_SecYByte));
            cmd = DRV_IOW(DsMacsecDestSecYByteStats_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, secYId, cmd, &tx_SecYByte));
        }
    }
    SYS_DOT1AE_FOREACH_DP_END
  
    p_sys_stats = (sys_tmm_dot1ae_an_stats_t*)(p_chan->an_stats);
    p_stats->an_stats[0].out_pkts_protected += p_sys_stats[0].out_pkts_protected;
    p_stats->an_stats[0].out_pkts_encrypted += p_sys_stats[0].out_pkts_encrypted;
    p_stats->an_stats[0].in_pkts_ok += p_sys_stats[0].in_pkts_ok;
    p_stats->an_stats[0].in_pkts_unchecked += p_sys_stats[0].in_pkts_unchecked;
    p_stats->an_stats[0].in_pkts_delayed += p_sys_stats[0].in_pkts_delayed;
    p_stats->an_stats[0].in_pkts_invalid += p_sys_stats[0].in_pkts_invalid;
    p_stats->an_stats[0].in_pkts_not_valid += p_sys_stats[0].in_pkts_not_valid;
    p_stats->an_stats[0].in_pkts_late += p_sys_stats[0].in_pkts_late;
    p_stats->an_stats[0].in_pkts_not_using_sa += p_sys_stats[0].in_pkts_not_using_sa;
    p_stats->an_stats[0].in_pkts_unused_sa += p_sys_stats[0].in_pkts_unused_sa;

    p_stats->an_stats[0].in_pkts_badtag +=  p_sys_stats[0].in_pkts_badtag;
    p_stats->an_stats[0].in_octets_decrypted +=  p_sys_stats[0].in_octets_decrypted;
    p_stats->an_stats[0].in_octets_validated +=  p_sys_stats[0].in_octets_validated;
    p_stats->an_stats[0].out_pkts_untagged +=  p_sys_stats[0].out_pkts_untagged;
    p_stats->an_stats[0].out_pkts_toolong +=  p_sys_stats[0].out_pkts_toolong;
    p_stats->an_stats[0].out_pkts_sa_not_inuse +=  p_sys_stats[0].out_pkts_sa_not_inuse;
    p_stats->an_stats[0].out_octets_encrypted +=  p_sys_stats[0].out_octets_encrypted;
    p_stats->an_stats[0].out_octets_protected +=  p_sys_stats[0].out_octets_protected;

    p_sys_stats[0].out_pkts_protected = p_stats->an_stats[0].out_pkts_protected;
    p_sys_stats[0].out_pkts_encrypted = p_stats->an_stats[0].out_pkts_encrypted;
    p_sys_stats[0].in_pkts_ok = p_stats->an_stats[0].in_pkts_ok;
    p_sys_stats[0].in_pkts_unchecked = p_stats->an_stats[0].in_pkts_unchecked;
    p_sys_stats[0].in_pkts_delayed = p_stats->an_stats[0].in_pkts_delayed;
    p_sys_stats[0].in_pkts_invalid = p_stats->an_stats[0].in_pkts_invalid;
    p_sys_stats[0].in_pkts_not_valid = p_stats->an_stats[0].in_pkts_not_valid;
    p_sys_stats[0].in_pkts_late = p_stats->an_stats[0].in_pkts_late;
    p_sys_stats[0].in_pkts_not_using_sa = p_stats->an_stats[0].in_pkts_not_using_sa;
    p_sys_stats[0].in_pkts_unused_sa = p_stats->an_stats[0].in_pkts_unused_sa;

    p_sys_stats[0].in_pkts_badtag =  p_stats->an_stats[0].in_pkts_badtag ;
    p_sys_stats[0].in_octets_decrypted = p_stats->an_stats[0].in_octets_decrypted ;
    p_sys_stats[0].in_octets_validated = p_stats->an_stats[0].in_octets_validated ;
    p_sys_stats[0].out_pkts_untagged = p_stats->an_stats[0].out_pkts_untagged ;
    p_sys_stats[0].out_pkts_toolong = p_stats->an_stats[0].out_pkts_toolong ;
    p_sys_stats[0].out_pkts_sa_not_inuse = p_stats->an_stats[0].out_pkts_sa_not_inuse ;
    p_sys_stats[0].out_octets_encrypted = p_stats->an_stats[0].out_octets_encrypted ;
    p_sys_stats[0].out_octets_protected = p_stats->an_stats[0].out_octets_protected ;

    if (p_chan->p2mp)
    {
        p_stats->an_stats[0].in_pkts_badtag = 0;
        p_stats->an_stats[0].in_octets_decrypted = 0;
        p_stats->an_stats[0].in_octets_validated = 0;
        p_stats->an_stats[0].out_pkts_untagged = 0;
        p_stats->an_stats[0].out_pkts_toolong = 0;
        p_stats->an_stats[0].in_pkts_not_using_sa = 0;
        p_stats->an_stats[0].in_pkts_unused_sa = 0;
        p_stats->an_stats[0].out_octets_encrypted = 0;
        p_stats->an_stats[0].out_octets_protected = 0;
    }
    return CTC_E_NONE;
}

int32
sys_tmm_dot1ae_get_secy_stats(uint8 lchip, uint32 gport, uint8 dir, void* p_stats)
{
    sys_traverse_t user_data;
    ctc_dot1ae_an_stats_t* p_secy_stats =NULL;
    SYS_DOT1AE_INIT_CHECK(lchip);
    p_secy_stats = (ctc_dot1ae_an_stats_t*)p_stats;
    sal_memset(&user_data, 0 , sizeof(sys_traverse_t));
    user_data.value1 = gport;
    user_data.value2 = dir;
    user_data.value3 = lchip;
    user_data.data =  p_secy_stats;
    CTC_ERROR_RETURN(ctc_hash_traverse(usw_dot1ae_master[lchip]->chan_hash, (hash_traversal_fn)_sys_tmm_lkup_sec_chan_by_port_traverse, (void *)&user_data));

    return CTC_E_NONE;
}

int32
sys_tmm_dot1ae_sync_dma_stats(uint8 lchip, void* p_data)
{
    uint32 type = 0;
    uint32* p_addr = NULL;
    sys_traverse_t user_data;
    sys_dma_reg_t* p_dma_reg = (sys_dma_reg_t*)p_data;
    type = *((uint32*)p_dma_reg->p_ext);
    p_addr = p_dma_reg->p_data;
    sal_memset(&user_data, 0 ,sizeof(sys_traverse_t));
    user_data.value2 = type;
    user_data.data = (void*)p_addr;
    user_data.value1 = lchip;
    CTC_ERROR_RETURN(ctc_hash_traverse(usw_dot1ae_master[lchip]->chan_hash, (hash_traversal_fn)_sys_tmm_dot1ae_sync_dma_traverse, (void *)&user_data));
    return CTC_E_NONE;
}
#if 0
int32
sys_tmm_isr_dot1ae_process_isr(uint8 gchip, void* p_data)
{
    uint16 chan_num = 0;
    ctc_dot1ae_event_t* p_event = NULL;
    uint8 lchip = 0;

    CTC_PTR_VALID_CHECK(p_data);
    CTC_ERROR_RETURN(sys_usw_get_local_chip_id(gchip, &lchip));
    SYS_DOT1AE_INIT_CHECK(lchip);
    SYS_LCHIP_CHECK_ACTIVE(lchip);
    p_event = (ctc_dot1ae_event_t*)p_data;
    for (chan_num = 0; chan_num < p_event->valid_num; chan_num++)
    {
         SYS_DOT1AE_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Dot1AE Event,  Chan ID: %u,  Sa inuse:%d Dir: %s\n",
            p_event->event_entry[chan_num].chan_id, p_event->event_entry[chan_num].sa_inuse,
            p_event->event_entry[chan_num].dir == CTC_DOT1AE_SC_DIR_TX? "Tx" : "Rx");
        CTC_ERROR_DUMP(_sys_tmm_dot1ae_isr_get_defect_name(lchip, &p_event->event_entry[chan_num]));
    }
    return CTC_E_NONE;
}

STATIC int32
sys_tmm_dot1ae_isr_defect(uint8 lchip, uint32 intr, void* p_data)
{
    uint8 gchip = 0;
    ctc_dot1ae_event_t event;
    CTC_INTERRUPT_EVENT_FUNC dot1ae_intrp_cb = NULL;
    uint32 do_intr_table_cnt = 0;
    uint32 do_intr_table_num = 0;
    int32 ret = CTC_E_NONE;
    MacsecReceiveScIntrp_m ds_rcv_intrp;
    MacsecTransmitScIntrp_m ds_send_intrp;
    uint32 rcv_event_bitmap = 0;
    uint32 send_event_bitmap = 0;
    sys_dot1ae_chan_t  sys_sec_chan;
    uint32 cmd = 0;
    uint8 dp_id = 0;
    sys_traverse_t user_data;
    SYS_DOT1AE_INIT_CHECK(lchip);
    SYS_DOT1AE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    sal_memset(&user_data, 0 , sizeof(sys_traverse_t));
    sal_memset(&sys_sec_chan, 0 , sizeof(sys_dot1ae_chan_t));
    CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip));
    CTC_ERROR_RETURN(sys_usw_interrupt_get_event_cb(lchip, CTC_EVENT_DOT1AE, &dot1ae_intrp_cb));
    if (!dot1ae_intrp_cb)
    {
        return CTC_E_NOT_INIT;
    }
    sal_memset(&event, 0, sizeof(ctc_dot1ae_event_t));
    SYS_DOT1AE_LOCK(lchip);
    do_intr_table_num = MCHIP_CAP(SYS_CAP_DOT1AE_SEC_CHAN_NUM);
    for (do_intr_table_cnt = 0; do_intr_table_cnt < do_intr_table_num; do_intr_table_cnt++)
    {
        cmd = DRV_IOR(MacsecReceiveScIntrp_t,   DRV_ENTRY_FLAG);
        CTC_ERROR_GOTO(DRV_IOCTL(lchip, do_intr_table_cnt, cmd, &ds_rcv_intrp), ret, End);
        rcv_event_bitmap = GetMacsecReceiveScIntrp(V, intrp_f, &ds_rcv_intrp);

        cmd = DRV_IOR(MacsecTransmitScIntrp_t,   DRV_ENTRY_FLAG);
        CTC_ERROR_GOTO(DRV_IOCTL(lchip, do_intr_table_cnt, cmd, &ds_send_intrp), ret, End);
        send_event_bitmap = GetMacsecTransmitScIntrp(V, intrp_f, &ds_send_intrp);
        dp_id = (do_intr_table_cnt > (MCHIP_CAP(SYS_CAP_DOT1AE_TX_CHAN_NUM)-1))? 1 : 0;
        sys_sec_chan.dp_id = dp_id;
        sys_sec_chan.sc_index= do_intr_table_cnt;
        if (rcv_event_bitmap)
        {
           sys_sec_chan.dir = CTC_DOT1AE_SC_DIR_RX;
           user_data.data = (void*)&sys_sec_chan;
           ctc_hash_traverse(usw_dot1ae_master[lchip]->chan_hash, (hash_traversal_fn)_sys_tmm_dot1ae_get_chan_by_idx_traverse, (void *)&user_data);
            event.event_entry[event.valid_num].chan_id = sys_sec_chan.chan_id;
            if (CTC_IS_BIT_SET(rcv_event_bitmap, 0))
            {
                CTC_SET_FLAG(event.event_entry[event.valid_num].event_bmp, CTC_DOT1AE_EVENT_PN_OVER_FLOW);
            }
            if (1 == SDK_WORK_PLATFORM)
            {
                rcv_event_bitmap = 0;
                cmd = DRV_IOW(MacsecReceiveScIntrp_t,   MacsecReceiveScIntrp_intrp_f);
                CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, do_intr_table_cnt, cmd, &rcv_event_bitmap), ret, End);
            }
            event.event_entry[event.valid_num].sa_inuse = sys_sec_chan.an_en;
            event.event_entry[event.valid_num].dir = CTC_DOT1AE_SC_DIR_RX;
            event.valid_num++;
        }
        if (event.valid_num >= CTC_DOT1AE_EVENT_MAX_NUM)
        {
            SYS_DOT1AE_UNLOCK(lchip);
            CTC_ERROR_RETURN(dot1ae_intrp_cb(gchip, &event));
            SYS_DOT1AE_LOCK(lchip);
            event.valid_num = 0;
        }
        if (send_event_bitmap)
        {
            sys_sec_chan.dir = CTC_DOT1AE_SC_DIR_TX;
            user_data.data = (void*)&sys_sec_chan;
            ctc_hash_traverse(usw_dot1ae_master[lchip]->chan_hash, (hash_traversal_fn)_sys_tmm_dot1ae_get_chan_by_idx_traverse, (void *)&user_data);
            event.event_entry[event.valid_num].chan_id = sys_sec_chan.chan_id;

            if (CTC_IS_BIT_SET(send_event_bitmap, 0))
            {
                CTC_SET_FLAG(event.event_entry[event.valid_num].event_bmp, CTC_DOT1AE_EVENT_PN_OVER_FLOW);
            }
            if (1 == SDK_WORK_PLATFORM)
            {
                send_event_bitmap = 0;
                cmd = DRV_IOW(MacsecTransmitScIntrp_t,   MacsecTransmitScIntrp_intrp_f);
                CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, do_intr_table_cnt, cmd, &send_event_bitmap), ret, End);
            }
            event.event_entry[event.valid_num].sa_inuse = sys_sec_chan.an_en;
            event.event_entry[event.valid_num].dir = CTC_DOT1AE_SC_DIR_TX;
            event.valid_num++;
        }
        if (event.valid_num >= CTC_DOT1AE_EVENT_MAX_NUM)
        {
            SYS_DOT1AE_UNLOCK(lchip);
            CTC_ERROR_RETURN(dot1ae_intrp_cb(gchip, &event));
            SYS_DOT1AE_LOCK(lchip);
            event.valid_num = 0;
        }
    }

    if (event.valid_num > 0)
    {
        SYS_DOT1AE_UNLOCK(lchip);
        CTC_ERROR_RETURN(dot1ae_intrp_cb(gchip, &event));
        SYS_DOT1AE_LOCK(lchip);
    }

End:
    SYS_DOT1AE_UNLOCK(lchip);
    return ret;
}
#endif

int32
sys_tmm_dot1ae_register_init(uint8 lchip)
{
    uint32 cmd = 0;
    uint32 value = 0;
    uint32 val_ary[2] = {0};
    MacsecParserCtl_m macsec_parser_ctl;
    MacsecRxCtl_m macsec_rx_ctl;
    MacsecTxCtl_m macsec_tx_ctl;
    MacSecDecCtl_m macsec_de_ctl;
    MacSecEncCtl_m macsec_en_ctl;
    uint8 idx =0;
    sal_memset(&macsec_parser_ctl, 0, sizeof(MacsecParserCtl_m));
    sal_memset(&macsec_rx_ctl, 0, sizeof(MacsecRxCtl_m));
    sal_memset(&macsec_tx_ctl, 0, sizeof(MacsecTxCtl_m));
    sal_memset(&macsec_de_ctl, 0, sizeof(MacSecDecCtl_m));
    sal_memset(&macsec_en_ctl, 0, sizeof(MacSecEncCtl_m));

    for (idx = 0; idx < 2; idx++)
    {
        cmd = DRV_IOR(MacsecParserCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, idx, cmd, &macsec_parser_ctl));
        SetMacsecParserCtl(V, cloudSecTypeChk_f, &macsec_parser_ctl, 1);
        SetMacsecParserCtl(V, versionChk_f, &macsec_parser_ctl, 1);
        SetMacsecParserCtl(V, scbChk_f, &macsec_parser_ctl, 1);
        SetMacsecParserCtl(V, slChk_f, &macsec_parser_ctl, 1);
        SetMacsecParserCtl(V, scEsChk_f, &macsec_parser_ctl, 1);
        SetMacsecParserCtl(V, pnChk_f, &macsec_parser_ctl, 0);
        cmd = DRV_IOW(MacsecParserCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, idx, cmd, &macsec_parser_ctl));

        /*MacsecRxCtl*/
        cmd = DRV_IOR(MacsecRxCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, idx, cmd, &macsec_rx_ctl));
        value =  MCHIP_CAP(SYS_CAP_CHANID_ILOOP);
        SetMacsecRxCtl(V, cfgILoopChanId0_f, &macsec_rx_ctl, value);

        value = MCHIP_CAP(SYS_CAP_CHANID_OAM);
        SetMacsecRxCtl(V, cfgILoopChanId1_f, &macsec_rx_ctl, value);

        value = MCHIP_CAP(SYS_CAP_CHANID_ELOG);
        SetMacsecRxCtl(V, cfgILoopChanId2_f, &macsec_rx_ctl, value);

        value = MCHIP_CAP(SYS_CAP_CHANID_DMA_RX0);
        SetMacsecRxCtl(V, cfgILoopChanId3_f, &macsec_rx_ctl, value);

        value =  MCHIP_CAP(SYS_CAP_NETWORK_CHANNEL_NUM) - 1;
        SetMacsecRxCtl(V, maxNetworkChanId_f, &macsec_rx_ctl, value);

        SetMacsecRxCtl(V, cipherModeChk_f, &macsec_rx_ctl, 1);
        SetMacsecRxCtl(V, macsecEtherType0_f, &macsec_rx_ctl, 0x88E5);
        SetMacsecRxCtl(V, macsecEtherType1_f, &macsec_rx_ctl, 0x88E5);
        SetMacsecRxCtl(V, macsecEtherType2_f, &macsec_rx_ctl, 0x88E5);
        SetMacsecRxCtl(V, macsecEtherType3_f, &macsec_rx_ctl, 0x88E5);
        SetMacsecRxCtl(V, cloudSecPlainUdpDestPort_f, &macsec_rx_ctl, 4789);
        SetMacsecRxCtl(V, invalidIcvNotCountOct_f, &macsec_rx_ctl, 1);
        SetMacsecRxCtl(V, validateDisableBypass_f, &macsec_rx_ctl, 1);
        SetMacsecRxCtl(V, pnThreshold0_f, &macsec_rx_ctl, 0xc0000000);
        val_ary[0] = 0x0;
        val_ary[1] = 0xc0000000;
        SetMacsecRxCtl(A, xpnThreshold0_f, &macsec_rx_ctl, val_ary);

        /*control packet use same udp port with data packet*/
        SetMacsecRxCtl(V, cloudsecControlUseSameUdpPort_f, &macsec_rx_ctl, 0);

        /*private Sectag use uncontrol port*/
        SetMacsecRxCtl(V, privateSectagUseUcPort_f, &macsec_rx_ctl, 1);
        cmd = DRV_IOW(MacsecRxCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, idx, cmd, &macsec_rx_ctl));

        /*MacsecTxCtl*/
        cmd = DRV_IOR(MacsecTxCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, idx, cmd, &macsec_tx_ctl));
        SetMacsecTxCtl(V, macsecEtherType0_f, &macsec_tx_ctl, 0x88E5);
        SetMacsecTxCtl(V, macsecEtherType1_f, &macsec_tx_ctl, 0x88E5);
        SetMacsecTxCtl(V, macsecEtherType2_f, &macsec_tx_ctl, 0x88E5);
        SetMacsecTxCtl(V, macsecEtherType3_f, &macsec_tx_ctl, 0x88E5);
        SetMacsecTxCtl(V, shortLengthFollowTm_f, &macsec_tx_ctl, 1);
        SetMacsecTxCtl(V, pnThreshold0_f, &macsec_tx_ctl, 0xc0000000);
        val_ary[0] = 0x0;
        val_ary[1] = 0xc0000000;
        SetMacsecTxCtl(A, xpnThreshold0_f, &macsec_tx_ctl, val_ary);

        cmd = DRV_IOW(MacsecTxCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, idx, cmd, &macsec_tx_ctl));

        SetMacSecDecCtl(V, clearOnReadReceiveScIntrp_f, &macsec_de_ctl, 1);
        SetMacSecDecCtl(V, clearOnReadScStatsEn_f, &macsec_de_ctl, 1);
        SetMacSecDecCtl(V, clearOnReadSecYByteStatsEn_f, &macsec_de_ctl, 1);
        SetMacSecDecCtl(V, clearOnReadSecYStatsEn_f, &macsec_de_ctl, 1);
        cmd = DRV_IOW(MacSecDecCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, idx, cmd, &macsec_de_ctl));

        SetMacSecEncCtl(V, clearOnReadDestSecYByteStatsEn_f, &macsec_en_ctl, 1);
        SetMacSecEncCtl(V, clearOnReadDestSecYStatsEn_f, &macsec_en_ctl, 1);
        SetMacSecEncCtl(V, clearOnReadTransmitScIntrp_f, &macsec_en_ctl, 1);
        SetMacSecEncCtl(V, clearOnReadTransmitScStatsEn_f, &macsec_en_ctl, 1);
        cmd = DRV_IOW(MacSecEncCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, idx, cmd, &macsec_en_ctl));

    }


    /*IpePreLookupCtl*/
    value = 1;
    cmd = DRV_IOW(IpePreLookupCtl_t, IpePreLookupCtl_advMacsecKeepException_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));
    cmd = DRV_IOW(IpePreLookupCtl_t, IpePreLookupCtl_advMacsecObeyDiscard_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));
    #if 0
    CTC_ERROR_RETURN(sys_usw_interrupt_register_event_cb(lchip, CTC_EVENT_DOT1AE, sys_tmm_isr_dot1ae_process_isr));
    CTC_ERROR_RETURN(sys_usw_interrupt_register_isr(lchip, SYS_INTR_FUNC_DP0_MACSEC_TX, sys_tmm_dot1ae_isr_defect));
    CTC_ERROR_RETURN(sys_usw_interrupt_register_isr(lchip, SYS_INTR_FUNC_DP0_MACSEC_RX, sys_tmm_dot1ae_isr_defect));
    CTC_ERROR_RETURN(sys_usw_interrupt_register_isr(lchip, SYS_INTR_FUNC_DP1_MACSEC_RX, sys_tmm_dot1ae_isr_defect));
    CTC_ERROR_RETURN(sys_usw_interrupt_register_isr(lchip, SYS_INTR_FUNC_DP1_MACSEC_TX, sys_tmm_dot1ae_isr_defect));
#endif
    CTC_ERROR_RETURN(SYS_CB_REGISTER(lchip, SYS_CB_DOT1AE_GET_SECY_STATS, sys_tmm_dot1ae_get_secy_stats));

    return CTC_E_NONE;

}
#endif
#endif

